void LibEventServer::stop() { Lock lock(m_mutex); if (getStatus() != RunStatus::RUNNING || m_server == nullptr) return; #define SHUT_FBLISTEN 3 /* * Modifications to the Linux kernel to support shutting down a listen * socket for new connections only, but anything which has completed * the TCP handshake will still be accepted. This allows for un-accepted * connections to be queued and then wait until all queued requests are * actively being processed. */ if (RuntimeOption::ServerShutdownListenWait > 0 && m_accept_sock != -1 && shutdown(m_accept_sock, SHUT_FBLISTEN) == 0) { int noWorkCount = 0; for (int i = 0; i < RuntimeOption::ServerShutdownListenWait; i++) { // Give the acceptor thread time to clean out all requests Logger::Info( "LibEventServer stopping port %d: [%d/%d] a/q/e %d/%d/%d", m_port, i, RuntimeOption::ServerShutdownListenWait, getActiveWorker(), getQueuedJobs(), getLibEventConnectionCount()); sleep(1); // If we're not doing anything, break out quickly noWorkCount += (getQueuedJobs() == 0 && getActiveWorker() == 0); if (RuntimeOption::ServerShutdownListenNoWork > 0 && noWorkCount >= RuntimeOption::ServerShutdownListenNoWork) break; if (getLibEventConnectionCount() == 0 && getQueuedJobs() == 0 && getActiveWorker() == 0) break; } Logger::Info("LibEventServer stopped port %d: a/q/e %d/%d/%d", m_port, getActiveWorker(), getQueuedJobs(), getLibEventConnectionCount()); } // inform LibEventServer::onRequest() to stop queuing setStatus(RunStatus::STOPPING); // stop JobQueue processing m_dispatcher.stop(); // stop event loop setStatus(RunStatus::STOPPED); if (write(m_pipeStop.getIn(), "", 1) < 0) { // an error occured but we're in shutdown already, so ignore } m_dispatcherThread.waitForEnd(); // wait for the timeout thread to stop m_timeoutThreadData.stop(); m_timeoutThread.waitForEnd(); evhttp_free(m_server); m_server = nullptr; }
void ProxygenServer::timeoutExpired() noexcept { Logger::Info("%p: shutdown timer expired for ProxygenServer port=%d, " "state=%d, a/q/e %d/%d/%d", this, m_port, (int)m_shutdownState, getActiveWorker(), getQueuedJobs(), getLibEventConnectionCount()); // proceed to next shutdown phase doShutdown(); }
void ProxygenServer::reportShutdownStatus() { if (m_port != RuntimeOption::ServerPort) return; if (getStatus() == RunStatus::STOPPED) return; Logger::FInfo("Shutdown state={}, a/q/e/p {}/{}/{}/{}, RSS={}Mb", static_cast<int>(m_shutdownState), getActiveWorker(), getQueuedJobs(), getLibEventConnectionCount(), m_pendingTransports.size(), Process::GetProcessRSS(getpid())); m_worker.getEventBase()->runAfterDelay([this]{reportShutdownStatus();}, 500); }