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);
}
}
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 + ".");
}
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);
}
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);
}
}
}
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));
}
Aggregations