Search in sources :

Example 1 with DaemonThreadFactory

use of alma.acs.concurrent.DaemonThreadFactory in project ACS by ACS-Community.

the class ServicesDaemonTest method testStartAcsServiceIndividually.

/**
	 * Simple test that only uses the start_xxx and Stop_xxx methods of the daemon,
	 * which is one step up from the old acsStart method, but does not use the convenience
	 * of the service description. All services are started on the same host. Later they are stopped.
	 */
public void testStartAcsServiceIndividually() throws Throwable {
    DaemonCallbackImpl daemonCallbackImpl_1 = new DaemonCallbackImpl(logger);
    DaemonCallbackImpl daemonCallbackImpl_2 = new DaemonCallbackImpl(logger);
    DaemonCallbackImpl daemonCallbackImpl_3 = new DaemonCallbackImpl(logger);
    DaemonCallback dcb_1 = activateDaemonCallback(daemonCallbackImpl_1);
    DaemonCallback dcb_2 = activateDaemonCallback(daemonCallbackImpl_2);
    DaemonCallback dcb_3 = activateDaemonCallback(daemonCallbackImpl_3);
    List<Throwable> thrs = new ArrayList<Throwable>();
    try {
        // start naming service and wait till it's up
        daemonCallbackImpl_1.prepareWaitForDone("naming");
        daemon.start_naming_service(dcb_1, instanceNumber);
        assertTrue("Failed to start naming service in 10 s", daemonCallbackImpl_1.waitForDone(10, TimeUnit.SECONDS));
        logger.info("Got naming service");
        // start interface repository but don't wait for it yet ( start other services in parallel)
        daemonCallbackImpl_2.prepareWaitForDone("IFR");
        daemon.start_interface_repository(true, true, dcb_2, instanceNumber);
        // start CDB and wait till it's up
        daemonCallbackImpl_1.prepareWaitForDone("CDB");
        // TODO try explicit path ($ACS_CDB replacement)
        daemon.start_xml_cdb(dcb_1, instanceNumber, false, "");
        assertTrue("Failed to start CDB in 15 s", daemonCallbackImpl_1.waitForDone(15, TimeUnit.SECONDS));
        assertCDB();
        // start manager and wait till it's up
        daemonCallbackImpl_1.prepareWaitForDone("manager");
        daemon.start_manager("", dcb_1, instanceNumber, false);
        assertTrue("Failed to start the ACS manager in 10 s", daemonCallbackImpl_1.waitForDone(10, TimeUnit.SECONDS));
        assertManager();
        // now wait for the IR if necessary
        assertTrue("Failed to start interface repository 30 s after all other services have started", daemonCallbackImpl_2.waitForDone(30, TimeUnit.SECONDS));
        logger.info("Got the IFR");
        // start 3 of the 4 known notify services in parallel.
        // We want to call the start_notification_service method in parallel, which yields an even more parallel service start
        // than with calling this asynchronous method 3 times in a sequence.
        // @TODO Currently this test fails due to what seems a deadlock in the daemon. With just one NC factory it works, but with 3 we get a timeout.
        daemonCallbackImpl_1.prepareWaitForDone("NC factory default");
        daemonCallbackImpl_2.prepareWaitForDone("NC factory logging");
        daemonCallbackImpl_3.prepareWaitForDone("NC factory alarms");
        class NotifySrvStarter implements Callable<Void> {

            private final String srvName;

            private final DaemonCallback cb;

            NotifySrvStarter(String srvName, DaemonCallback cb) {
                this.srvName = srvName;
                this.cb = cb;
            }

            public Void call() throws Exception {
                daemon.start_notification_service(srvName, cb, instanceNumber);
                return null;
            }
        }
        ExecutorService pool = Executors.newFixedThreadPool(3, new DaemonThreadFactory());
        Future<Void> defaultNotifSrvFuture = pool.submit(new NotifySrvStarter(systemNotificationServiceDefault.value, dcb_1));
        Future<Void> loggingNotifSrvFuture = pool.submit(new NotifySrvStarter(systemNotificationServiceLogging.value, dcb_2));
        Future<Void> alarmNotifSrvFuture = pool.submit(new NotifySrvStarter(systemNotificationServiceAlarms.value, dcb_3));
        try {
            defaultNotifSrvFuture.get(20, TimeUnit.SECONDS);
            loggingNotifSrvFuture.get(20, TimeUnit.SECONDS);
            alarmNotifSrvFuture.get(20, TimeUnit.SECONDS);
        } catch (ExecutionException ex) {
            // throw the ex that came from the call() method
            throw ex.getCause();
        } catch (TimeoutException ex2) {
            fail("Failed to return from 'start_notification_service' within 20 seconds. ");
        }
        // now wait for the notification services to be actually started
        daemonCallbackImpl_1.waitForDone(10, TimeUnit.SECONDS);
        daemonCallbackImpl_2.waitForDone(10, TimeUnit.SECONDS);
        daemonCallbackImpl_3.waitForDone(10, TimeUnit.SECONDS);
    } catch (Throwable thr) {
        thrs.add(thr);
    } finally {
        // and then waiting for the asynch calls to finish.
        try {
            daemonCallbackImpl_1.prepareWaitForDone("stop NC factory default");
            daemon.stop_notification_service(systemNotificationServiceDefault.value, dcb_1, instanceNumber);
        } catch (Throwable thr) {
            thrs.add(thr);
        }
        try {
            daemonCallbackImpl_2.prepareWaitForDone("stop NC factory logging");
            daemon.stop_notification_service(systemNotificationServiceLogging.value, dcb_2, instanceNumber);
        } catch (Throwable thr) {
            thrs.add(thr);
        }
        try {
            daemonCallbackImpl_3.prepareWaitForDone("stop NC factory alarms");
            daemon.stop_notification_service(systemNotificationServiceAlarms.value, dcb_3, instanceNumber);
        } catch (Throwable thr) {
            thrs.add(thr);
        }
        try {
            assertTrue("Failed to stop the default NC factory in 10 s", daemonCallbackImpl_1.waitForDone(10, TimeUnit.SECONDS));
            assertTrue("Failed to stop the logging NC factory in 10 s", daemonCallbackImpl_2.waitForDone(10, TimeUnit.SECONDS));
            assertTrue("Failed to stop the logging NC factory in 10 s", daemonCallbackImpl_3.waitForDone(10, TimeUnit.SECONDS));
        } catch (Throwable thr) {
            thrs.add(thr);
        }
        // stop the IFR
        try {
            daemonCallbackImpl_1.prepareWaitForDone("stop IFR");
            daemon.stop_interface_repository(dcb_1, instanceNumber);
            assertTrue("Failed to stop the interface repository in 10 s", daemonCallbackImpl_1.waitForDone(10, TimeUnit.SECONDS));
        } catch (Throwable thr) {
            thrs.add(thr);
        }
        // stop the manager
        try {
            daemonCallbackImpl_1.prepareWaitForDone("stop manager");
            daemon.stop_manager("", dcb_1, instanceNumber);
            assertTrue("Failed to stop the manager in 10 s", daemonCallbackImpl_1.waitForDone(10, TimeUnit.SECONDS));
        } catch (Throwable thr) {
            thrs.add(thr);
        }
    }
    if (thrs.size() > 0) {
        logger.info("Failure: there were " + thrs.size() + " errors.");
        throw thrs.get(0);
    }
}
Also used : DaemonThreadFactory(alma.acs.concurrent.DaemonThreadFactory) ArrayList(java.util.ArrayList) Callable(java.util.concurrent.Callable) DaemonCallback(alma.acsdaemon.DaemonCallback) ExecutorService(java.util.concurrent.ExecutorService) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(java.util.concurrent.TimeoutException)

Example 2 with DaemonThreadFactory

use of alma.acs.concurrent.DaemonThreadFactory in project ACS by ACS-Community.

the class ManagerImpl method initialize.

/**
	 * Initializes Manager.
	 * @param	prevayler			implementation of prevayler system
	 * @param	context				remote directory implementation
	 */
public void initialize(Prevayler prevayler, CDBAccess cdbAccess, Context context, final Logger logger, ManagerContainerServices managerContainerServices) {
    this.prevayler = prevayler;
    this.remoteDirectory = context;
    this.logger = logger;
    // needs to be done here, since deserialization is used
    initializeDefaultConfiguration();
    if (cdbAccess != null)
        setCDBAccess(cdbAccess);
    readManagerConfiguration();
    componentsLock = (ProfilingReentrantLock.isProfilingEnabled ? new ProfilingReentrantLock("componentsLock") : new ReentrantLock());
    random = new Random();
    heartbeatTask = new Timer(true);
    delayedDeactivationTask = new Timer(true);
    containerLoggedInMonitor = new Object();
    activationSynchronization = new HashMap<String, ReferenceCountingLock>();
    activationPendingRWLock = new ReaderPreferenceReadWriteLock();
    shutdown = new AtomicBoolean(false);
    threadPool = new ThreadPoolExecutor(poolThreads, poolThreads, Long.MAX_VALUE, TimeUnit.NANOSECONDS, new LinkedBlockingQueue(), new DaemonThreadFactory("managerThreadPool"));
    managerCache = new HashMap<String, Manager>();
    pendingActivations = new HashMap<String, ComponentInfo>();
    pendingContainerShutdown = Collections.synchronizedSet(new HashSet<String>());
    pendingContainerAsyncRequests = new HashMap<String, Deque<ComponentInfoCompletionCallback>>();
    clientMessageQueue = new HashMap<Client, LinkedList<ClientMessageTask>>();
    groupedNotifyTaskMap = new HashMap<Object, GroupedNotifyTask>();
    threadsUsedPercentage = new AtomicInteger(0);
    // create threads
    threadPool.prestartAllCoreThreads();
    // read CDB startup
    try {
        String componentSpec = System.getProperty(NAME_CDB_COMPONENTSPEC);
        if (componentSpec != null) {
            cdbActivation = new ComponentSpec(componentSpec);
            logger.log(Level.INFO, "Using CDB component specification: '" + cdbActivation + "'.");
        }
    } catch (Throwable t) {
        logger.log(Level.WARNING, "Failed to parse '" + NAME_CDB_COMPONENTSPEC + "' variable, " + t.getMessage(), t);
    }
    // check load balancing strategy
    checkLoadBalancingStrategy();
    // establish connect to the alarm system
    try {
        alarmSource = new AlarmSourceImpl(managerContainerServices);
        alarmSource.start();
    } catch (Throwable ex) {
        logger.log(Level.SEVERE, "Failed to initialize Alarm System Interface " + ex.getMessage(), ex);
        alarmSource = null;
    }
    // register ping tasks
    initializePingTasks();
    // handle monitoring removal task
    final long timeInMs = enableHandleMonitoringDurationMins * 60L * 1000;
    if (enableHandleMonitoring && enableHandleMonitoringDurationMins > 0) {
        heartbeatTask.schedule(new TimerTask() {

            @Override
            public void run() {
                try {
                    logHandleCleanup(timeInMs);
                } catch (Throwable th) {
                    logger.log(Level.SEVERE, "Unexpected exception in handle log cleanup task.", th);
                }
            }
        }, 0, timeInMs);
    }
    // start topology sort manager
    topologySortManager = new ComponentInfoTopologicalSortManager(components, containers, activationPendingRWLock, pendingContainerShutdown, threadPool, logger);
    if (prevayler == null)
        statePersitenceFlag.set(false);
    String enDis = statePersitenceFlag.get() ? "enabled" : "disabled";
    logger.info("Manager initialized with state persistence " + enDis + ".");
}
Also used : DaemonThreadFactory(alma.acs.concurrent.DaemonThreadFactory) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) Manager(com.cosylab.acs.maci.Manager) Random(java.util.Random) TimerTask(java.util.TimerTask) AlarmSourceImpl(alma.acs.alarmsystem.source.AlarmSourceImpl) Client(com.cosylab.acs.maci.Client) LinkedHashSet(java.util.LinkedHashSet) HashSet(java.util.HashSet) ReentrantLock(java.util.concurrent.locks.ReentrantLock) ComponentSpec(com.cosylab.acs.maci.ComponentSpec) ArrayDeque(java.util.ArrayDeque) Deque(java.util.Deque) LinkedList(java.util.LinkedList) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Timer(java.util.Timer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) ComponentInfo(com.cosylab.acs.maci.ComponentInfo)

Example 3 with DaemonThreadFactory

use of alma.acs.concurrent.DaemonThreadFactory in project ACS by ACS-Community.

the class ComponentClient method initRemoteLogging.

/**
     * Sets up the client logger(s) to send log records to the remote log service.
     * This method starts a separate thread and returns immediately.
     * <p>
     * Makes repeated attempts to connect to the remote logger.
     * If they fail unexpectedly, remote logging will be disabled. 
     * <p>
     * If the <code>ComponentClient</code> has been constructed without an external <code>AcsCorba</code> object
     * (the normal case), then this method is called automatically. <br>
     * Otherwise (with an external <code>AcsCorba</code> object provided) it is assumed that also 
     * remote logging is controlled from outside of this class. If nonetheless you want to 
     * initialize remote logging, you may explicitly call this method for convenience.
     * <p>
     * Override this method to prevent remote logging (useful only if AcsCorba is is not provided externally).
	 */
public void initRemoteLogging() {
    Runnable cmd = new Runnable() {

        public void run() {
            boolean gotLogService = false;
            try {
                gotLogService = ClientLogManager.getAcsLogManager().initRemoteLogging(acsCorba.getORB(), m_acsManagerProxy.getManager(), m_acsManagerProxy.getManagerHandle(), true);
            } catch (Exception e) {
            // just log below
            }
            if (!gotLogService) {
                m_logger.log(Level.WARNING, "ACS central logging not available!");
                ClientLogManager.getAcsLogManager().suppressRemoteLogging();
            }
        }
    };
    ExecutorService executor = Executors.newSingleThreadExecutor(new DaemonThreadFactory("InitRemoteLogging"));
    executor.execute(cmd);
}
Also used : CleaningDaemonThreadFactory(alma.acs.container.CleaningDaemonThreadFactory) DaemonThreadFactory(alma.acs.concurrent.DaemonThreadFactory) ExecutorService(java.util.concurrent.ExecutorService)

Example 4 with DaemonThreadFactory

use of alma.acs.concurrent.DaemonThreadFactory in project ACS by ACS-Community.

the class RemoteLoggingTest method testConcurrentRemoteInitAndStop.

/**
	 * Tests the situation in which the ClientLogManager is shut down before it has finished the 
	 * asynchronous <code>initRemoteLogging</code> call.
	 * This can happen in a <code>ComponentClient</code>-based application that performs a short task.
	 * <p>
	 * It is important to make the stdout printing part of this test,
	 * e.g. by using TAT without output suppression tricks,
	 * because among other things we expect the string
	 * <code>Will abort ClientLogManager#initRemoteLogging because remote logging seems no longer needed.</code>
	 * when initRemoteLogging is interrupted by a shutdown.
	 * <p>
	 * The main test thread that logs some messages and the thread that calls initRemoteLogging 
	 * compete for the internal lock {@link ClientLogManager#logQueueLock}, whose functioning is being tested here.
	 * <p>
	 * <b>Unfortunately this cannot be totally deterministic, so we must accept occasional failures
	 * of the kind that the output contains "Remote log: <Info .../>" instead of "Will abort ..." strings, or vice versa.</b>
	 */
public void testConcurrentRemoteInitAndStop() throws InterruptedException {
    DaemonThreadFactory dtf = new DaemonThreadFactory(getName());
    // we try this out for different simulated network delays and shutdown delays
    // @TODO chose values that give deterministic results on most test machines.
    int[] networkDelays = { 0, 2, 16, 21, 100 };
    // @TODO chose values that give deterministic results on most test machines.
    int[] shutdownDelays = { 1, 20, 106 };
    for (int networkDelay : networkDelays) {
        // with the additional arrangement that initRemoteLogging was running when the last log was produced.
        for (int shutdownDelay : shutdownDelays) {
            System.out.println("\n*** Network delay = " + networkDelay + " and shutdown delay = " + shutdownDelay + " ***");
            CountDownLatch syncOnPrepareRemoteLogging = new CountDownLatch(1);
            final ClientLogManagerStandalone clm = new ClientLogManagerStandalone(syncOnPrepareRemoteLogging);
            LogConfig logConfig = clm.getLogConfig();
            logConfig.setDefaultMinLogLevel(AcsLogLevelDefinition.TRACE);
            logConfig.setDefaultMinLogLevelLocal(AcsLogLevelDefinition.TRACE);
            Logger logger = clm.getLoggerForApplication(getName(), true);
            // log something before we init the remote logging:
            logger.info("A healthy info log before initRemoteLogging (" + networkDelay + "/" + shutdownDelay + ")");
            // to keep these two logs in order, which makes manual ref file comparison easier. 
            Thread.sleep(2);
            logger.fine("now that was a fine log before initRemoteLogging (" + networkDelay + "/" + shutdownDelay + ")");
            // simulated network delay for initRemoteLogging-getLogService and write_records
            clm.setDelayMillis(networkDelay);
            // call initRemoteLogging from a separate thread
            Thread initRemoteLoggingThread = dtf.newThread(new Runnable() {

                public void run() {
                    initRemoteLogging(clm);
                }
            });
            initRemoteLoggingThread.start();
            // wait until this thread is actually running, which we check via notification from the ClientLogManager#prepareRemoteLogging method
            // timeout should never apply, just used to stop the test if it gets messed up. 
            assertTrue("initRemoteLogging should have called prepareRemoteLogging by now...", syncOnPrepareRemoteLogging.await(10, TimeUnit.SECONDS));
            logger.info("Another info log after initRemoteLogging (" + networkDelay + "/" + shutdownDelay + ")");
            // depending on the values of networkDelay and shutdownDelay, we may be calling shutdown while 
            // our ClientLogManager is still delivering the log messages.
            Thread.sleep(shutdownDelay);
            clm.shutdown(true);
            // wait for the thread that called initRemoteLogging
            initRemoteLoggingThread.join(10000);
            // wait a bit more for the mock log dispatcher to print out its xml log record
            Thread.sleep(1500);
        }
    }
}
Also used : DaemonThreadFactory(alma.acs.concurrent.DaemonThreadFactory) CountDownLatch(java.util.concurrent.CountDownLatch) Logger(java.util.logging.Logger) LogConfig(alma.acs.logging.config.LogConfig)

Example 5 with DaemonThreadFactory

use of alma.acs.concurrent.DaemonThreadFactory in project ACS by ACS-Community.

the class ProcessUtilTest method testJava.

/**
	 * Tests ProcesUtil with java processes
	 */
public void testJava() throws Exception {
    Class<?> testClass = ProcessUtilTestDummy.class;
    assertFalse(processUtil.isJavaProcessRunning(testClass));
    // run dummy process
    Process proc = runDummyProcess();
    ProcessStreamGobbler gobbler = new ProcessStreamGobbler(proc, new DaemonThreadFactory(), true);
    assertFalse("Dummy java process is supposed to still run after 3.5 seconds", gobbler.gobble(3500, TimeUnit.MILLISECONDS));
    assertTrue(processUtil.isJavaProcessRunning(testClass));
    List<String> stdout = gobbler.getStdout();
    int msgCount = 0;
    for (String msg : stdout) {
        if (msg.startsWith("All is well ")) {
            // ignore other lines with acsStartJava script output
            msgCount++;
        }
    }
    assertEquals("Expected two 'All is well' messages in 3.5 seconds (after ~ 0 and 2 seconds).", 2, msgCount);
    List<String> stderr = gobbler.getStderr();
    assertEquals(0, stderr.size());
    // get PID of dummy process	
    List<String> pidList = processUtil.getJavaPIDs(testClass);
    assertEquals("Expected to find one running instance of " + testClass.getName() + ".", 1, pidList.size());
    logger.info("Found single dummy java class with PID=" + pidList.get(0));
    // kill process
    processUtil.killProcess(pidList.get(0), true);
    assertFalse(processUtil.isJavaProcessRunning(testClass));
}
Also used : ProcessStreamGobbler(alma.acs.util.ProcessStreamGobbler) DaemonThreadFactory(alma.acs.concurrent.DaemonThreadFactory)

Aggregations

DaemonThreadFactory (alma.acs.concurrent.DaemonThreadFactory)8 ExecutorService (java.util.concurrent.ExecutorService)3 ProcessStreamGobbler (alma.acs.util.ProcessStreamGobbler)2 ArrayList (java.util.ArrayList)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 AlarmSourceImpl (alma.acs.alarmsystem.source.AlarmSourceImpl)1 CleaningDaemonThreadFactory (alma.acs.container.CleaningDaemonThreadFactory)1 LogConfig (alma.acs.logging.config.LogConfig)1 DaemonCallback (alma.acsdaemon.DaemonCallback)1 Client (com.cosylab.acs.maci.Client)1 ComponentInfo (com.cosylab.acs.maci.ComponentInfo)1 ComponentSpec (com.cosylab.acs.maci.ComponentSpec)1 Manager (com.cosylab.acs.maci.Manager)1 IOException (java.io.IOException)1 ArrayDeque (java.util.ArrayDeque)1 ConcurrentModificationException (java.util.ConcurrentModificationException)1 Deque (java.util.Deque)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 LinkedHashSet (java.util.LinkedHashSet)1