Inits(RealVoltDB rvdb, int threadCount) { m_rvdb = rvdb; m_config = rvdb.m_config; // determine if this is a rejoining node // (used for license check and later the actual rejoin) if (m_config.m_startAction.doesRejoin()) { m_isRejoin = true; } else { m_isRejoin = false; } m_threadCount = threadCount; m_deployment = rvdb.m_catalogContext.getDeployment(); // find all the InitWork subclasses using reflection and load them up Class<?>[] declaredClasses = Inits.class.getDeclaredClasses(); for (Class<?> cls : declaredClasses) { // skip base classes and fake classes if (cls == InitWork.class) continue; if (cls == COMPLETION_WORK.class) continue; if (InitWork.class.isAssignableFrom(cls)) { InitWork instance = null; try { Constructor<?> constructor = cls.getDeclaredConstructor(Inits.class); instance = (InitWork) constructor.newInstance(this); } catch (Exception e) { VoltDB.crashLocalVoltDB("Critical error loading class " + cls.getName(), true, e); } m_jobs.put(instance.getClass(), instance); } } // make blockers and blockees symmetrical for (InitWork iw : m_jobs.values()) { for (Class<? extends InitWork> cls : iw.m_blockers) { InitWork blocker = m_jobs.get(cls); blocker.m_blockees.add(iw.getClass()); } } // collect initially ready jobs List<Class<? extends InitWork>> toRemove = new ArrayList<Class<? extends InitWork>>(); for (Entry<Class<? extends InitWork>, InitWork> e : m_jobs.entrySet()) { if (e.getValue().m_blockers.size() == 0) { toRemove.add(e.getKey()); m_readyJobs.add(e.getValue()); } } }
@Override public void run() { while (true) { InitWork iw = null; try { iw = m_readyJobs.take(); } catch (InterruptedException e) { VoltDB.crashLocalVoltDB(e.getMessage(), true, e); } if (iw instanceof COMPLETION_WORK) return; // hostLog.info("Running InitWorker: " + iw.getClass().getName()); iw.run(); completeInitWork(iw); } }
synchronized void completeInitWork(InitWork iw) { m_jobs.remove(iw.getClass()); for (Class<? extends InitWork> cls : iw.m_blockees) { InitWork blockee = m_jobs.get(cls); boolean success = blockee.m_blockers.remove(iw.getClass()); assert (success); if (blockee.m_blockers.size() == 0) { m_readyJobs.add(blockee); } } if (m_jobs.size() == 0) { // tell all the threads to stop for (int i = 0; i < m_threadCount; ++i) { m_readyJobs.add(new COMPLETION_WORK()); } } }