diff options
author | shmel1k <shmel1k@ydb.tech> | 2023-11-26 18:16:14 +0300 |
---|---|---|
committer | shmel1k <shmel1k@ydb.tech> | 2023-11-26 18:43:30 +0300 |
commit | b8cf9e88f4c5c64d9406af533d8948deb050d695 (patch) | |
tree | 218eb61fb3c3b96ec08b4d8cdfef383104a87d63 /contrib/python/Twisted/py2/twisted/application/runner/_runner.py | |
parent | 523f645a83a0ec97a0332dbc3863bb354c92a328 (diff) | |
download | ydb-b8cf9e88f4c5c64d9406af533d8948deb050d695.tar.gz |
add kikimr_configure
Diffstat (limited to 'contrib/python/Twisted/py2/twisted/application/runner/_runner.py')
-rw-r--r-- | contrib/python/Twisted/py2/twisted/application/runner/_runner.py | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/contrib/python/Twisted/py2/twisted/application/runner/_runner.py b/contrib/python/Twisted/py2/twisted/application/runner/_runner.py new file mode 100644 index 0000000000..7542a5b9a9 --- /dev/null +++ b/contrib/python/Twisted/py2/twisted/application/runner/_runner.py @@ -0,0 +1,185 @@ +# -*- test-case-name: twisted.application.runner.test.test_runner -*- +# Copyright (c) Twisted Matrix Laboratories. +# See LICENSE for details. + +""" +Twisted application runner. +""" + +from sys import stderr +from signal import SIGTERM +from os import kill + +from attr import attrib, attrs, Factory + +from twisted.logger import ( + globalLogBeginner, textFileLogObserver, + FilteringLogObserver, LogLevelFilterPredicate, + LogLevel, Logger, +) + +from ._exit import exit, ExitStatus +from ._pidfile import nonePIDFile, AlreadyRunningError, InvalidPIDFileError + + + +@attrs(frozen=True) +class Runner(object): + """ + Twisted application runner. + + @cvar _log: The logger attached to this class. + @type _log: L{Logger} + + @ivar _reactor: The reactor to start and run the application in. + @type _reactor: L{IReactorCore} + + @ivar _pidFile: The file to store the running process ID in. + @type _pidFile: L{IPIDFile} + + @ivar _kill: Whether this runner should kill an existing running + instance of the application. + @type _kill: L{bool} + + @ivar _defaultLogLevel: The default log level to start the logging + system with. + @type _defaultLogLevel: L{constantly.NamedConstant} from L{LogLevel} + + @ivar _logFile: A file stream to write logging output to. + @type _logFile: writable file-like object + + @ivar _fileLogObserverFactory: A factory for the file log observer to + use when starting the logging system. + @type _pidFile: callable that takes a single writable file-like object + argument and returns a L{twisted.logger.FileLogObserver} + + @ivar _whenRunning: Hook to call after the reactor is running; + this is where the application code that relies on the reactor gets + called. + @type _whenRunning: callable that takes the keyword arguments specified + by C{whenRunningArguments} + + @ivar _whenRunningArguments: Keyword arguments to pass to + C{whenRunning} when it is called. + @type _whenRunningArguments: L{dict} + + @ivar _reactorExited: Hook to call after the reactor exits. + @type _reactorExited: callable that takes the keyword arguments + specified by C{reactorExitedArguments} + + @ivar _reactorExitedArguments: Keyword arguments to pass to + C{reactorExited} when it is called. + @type _reactorExitedArguments: L{dict} + """ + + _log = Logger() + + _reactor = attrib() + _pidFile = attrib(default=nonePIDFile) + _kill = attrib(default=False) + _defaultLogLevel = attrib(default=LogLevel.info) + _logFile = attrib(default=stderr) + _fileLogObserverFactory = attrib(default=textFileLogObserver) + _whenRunning = attrib(default=lambda **_: None) + _whenRunningArguments = attrib(default=Factory(dict)) + _reactorExited = attrib(default=lambda **_: None) + _reactorExitedArguments = attrib(default=Factory(dict)) + + + def run(self): + """ + Run this command. + """ + pidFile = self._pidFile + + self.killIfRequested() + + try: + with pidFile: + self.startLogging() + self.startReactor() + self.reactorExited() + + except AlreadyRunningError: + exit(ExitStatus.EX_CONFIG, "Already running.") + return # When testing, patched exit doesn't exit + + + def killIfRequested(self): + """ + If C{self._kill} is true, attempt to kill a running instance of the + application. + """ + pidFile = self._pidFile + + if self._kill: + if pidFile is nonePIDFile: + exit(ExitStatus.EX_USAGE, "No PID file specified.") + return # When testing, patched exit doesn't exit + + try: + pid = pidFile.read() + except EnvironmentError: + exit(ExitStatus.EX_IOERR, "Unable to read PID file.") + return # When testing, patched exit doesn't exit + except InvalidPIDFileError: + exit(ExitStatus.EX_DATAERR, "Invalid PID file.") + return # When testing, patched exit doesn't exit + + self.startLogging() + self._log.info("Terminating process: {pid}", pid=pid) + + kill(pid, SIGTERM) + + exit(ExitStatus.EX_OK) + return # When testing, patched exit doesn't exit + + + def startLogging(self): + """ + Start the L{twisted.logger} logging system. + """ + logFile = self._logFile + + fileLogObserverFactory = self._fileLogObserverFactory + + fileLogObserver = fileLogObserverFactory(logFile) + + logLevelPredicate = LogLevelFilterPredicate( + defaultLogLevel=self._defaultLogLevel + ) + + filteringObserver = FilteringLogObserver( + fileLogObserver, [logLevelPredicate] + ) + + globalLogBeginner.beginLoggingTo([filteringObserver]) + + + def startReactor(self): + """ + Register C{self._whenRunning} with the reactor so that it is called + once the reactor is running, then start the reactor. + """ + self._reactor.callWhenRunning(self.whenRunning) + + self._log.info("Starting reactor...") + self._reactor.run() + + + def whenRunning(self): + """ + Call C{self._whenRunning} with C{self._whenRunningArguments}. + + @note: This method is called after the reactor starts running. + """ + self._whenRunning(**self._whenRunningArguments) + + + def reactorExited(self): + """ + Call C{self._reactorExited} with C{self._reactorExitedArguments}. + + @note: This method is called after the reactor exits. + """ + self._reactorExited(**self._reactorExitedArguments) |