// Any logging prior to this point will not end up in the daemon log file. initialiseLogging(loggingManager, daemonLog);
// Detach the process from the parent terminal/console ProcessEnvironmentprocessEnvironment= daemonServices.get(ProcessEnvironment.class); processEnvironment.maybeDetachProcess();
LOGGER.debug("Assuming the daemon was started with following jvm opts: {}", startupOpts); // 开启后台daemon线程 Daemondaemon= daemonServices.get(Daemon.class); daemon.start();
publicvoidstart() { LOGGER.info("start() called on daemon - {}", daemonContext); lifecycleLock.lock(); try { if (stateCoordinator != null) { thrownewIllegalStateException("cannot start daemon as it is already running"); }
// Generate an authentication token, which must be provided by the client in any requests it makes SecureRandomsecureRandom=newSecureRandom(); byte[] token = newbyte[16]; secureRandom.nextBytes(token);
ShutdownHooks.addShutdownHook(newRunnable() { @Override publicvoidrun() { try { daemonRegistry.remove(connectorAddress); } catch (Exception e) { LOGGER.debug("VM shutdown hook was unable to remove the daemon address from the registry. It will be cleaned up later.", e); } } });
publicclassDaemonTcpServerConnectorimplementsDaemonServerConnector { // ...... public Address start(final IncomingConnectionHandler handler, final Runnable connectionErrorHandler) { lifecycleLock.lock(); try { if (stopped) { throw ...... } if (started) { throw ...... }
// Hold the lock until we actually start accepting connections for the case when stop is called from another // thread while we are in the middle here.
publicclassDefaultIncomingConnectionHandlerimplementsIncomingConnectionHandler, Stoppable { @Override publicvoidhandle(SynchronizedDispatchConnection<Message> connection) { // Mark the connection has being handled onStartHandling(connection);
//we're spinning a thread to do work to avoid blocking the connection //This means that the Daemon potentially can do multiple things but we only allows a single build at a time
publicvoidstopOnExpiration(DaemonExpirationStrategy expirationStrategy, int checkIntervalMills) { LOGGER.debug("stopOnExpiration() called on daemon"); scheduleExpirationChecks(expirationStrategy, checkIntervalMills); awaitExpiration(); }
privatevoidawaitExpiration() { LOGGER.debug("awaitExpiration() called on daemon");
DaemonStateCoordinator stateCoordinator; lifecycleLock.lock(); try { if (this.stateCoordinator == null) { thrownewIllegalStateException("cannot await stop on daemon as it has not been started."); } stateCoordinator = this.stateCoordinator; } finally { lifecycleLock.unlock(); }
booleanawaitStop() { lock.lock(); try { while (true) { try { switch (state) { case Idle: case Busy: LOGGER.debug("daemon is running. Sleeping until state changes."); condition.await(); break; case Canceled: LOGGER.debug("cancel requested."); cancelNow(); break; case Broken: thrownewIllegalStateException("This daemon is in a broken state."); case StopRequested: LOGGER.debug("daemon stop has been requested. Sleeping until state changes."); condition.await(); break; case Stopped: LOGGER.debug("daemon has stopped."); returntrue; } } catch (InterruptedException e) { throw UncheckedException.throwAsUncheckedException(e); } } } finally { lock.unlock(); } }