Start using asyncio for signals
This commit is contained in:
parent
f26d95963e
commit
c6b5aab917
|
@ -7,7 +7,7 @@ An extremely modulable IRC bot, built around XML configuration files!
|
|||
Requirements
|
||||
------------
|
||||
|
||||
*nemubot* requires at least Python 3.3 to work.
|
||||
*nemubot* requires at least Python 3.4 to work, as it uses `asyncio`.
|
||||
|
||||
Connecting to SSL server requires [this patch](http://bugs.python.org/issue27629).
|
||||
|
||||
|
|
|
@ -178,25 +178,13 @@ def main():
|
|||
daemonize(args.socketfile, not args.no_attach)
|
||||
|
||||
# Signals handling
|
||||
def sigtermhandler(signum, frame):
|
||||
def sigtermhandler():
|
||||
"""On SIGTERM and SIGINT, quit nicely"""
|
||||
context.quit()
|
||||
signal.signal(signal.SIGINT, sigtermhandler)
|
||||
signal.signal(signal.SIGTERM, sigtermhandler)
|
||||
context.loop.add_signal_handler(signal.SIGINT, sigtermhandler)
|
||||
context.loop.add_signal_handler(signal.SIGTERM, sigtermhandler)
|
||||
|
||||
def sighuphandler(signum, frame):
|
||||
"""On SIGHUP, perform a deep reload"""
|
||||
nonlocal context
|
||||
|
||||
logger.debug("SIGHUP receive, iniate reload procedure...")
|
||||
|
||||
# Reload configuration file
|
||||
for path in args.files:
|
||||
if os.path.isfile(path):
|
||||
sync_act("loadconf", path)
|
||||
signal.signal(signal.SIGHUP, sighuphandler)
|
||||
|
||||
def sigusr1handler(signum, frame):
|
||||
def sigusr1handler():
|
||||
"""On SIGHUSR1, display stacktraces"""
|
||||
import threading, traceback
|
||||
for threadId, stack in sys._current_frames().items():
|
||||
|
@ -208,24 +196,21 @@ def main():
|
|||
logger.debug("########### Thread %s:\n%s",
|
||||
thName,
|
||||
"".join(traceback.format_stack(stack)))
|
||||
signal.signal(signal.SIGUSR1, sigusr1handler)
|
||||
context.loop.add_signal_handler(signal.SIGUSR1, sigusr1handler)
|
||||
|
||||
# Store PID to pidfile
|
||||
if args.pidfile is not None:
|
||||
with open(args.pidfile, "w+") as f:
|
||||
f.write(str(os.getpid()))
|
||||
|
||||
# context can change when performing an hotswap, always join the latest context
|
||||
oldcontext = None
|
||||
while oldcontext != context:
|
||||
oldcontext = context
|
||||
context.start()
|
||||
context.join()
|
||||
context.start()
|
||||
context.loop.run_forever()
|
||||
context.join()
|
||||
|
||||
# Wait for consumers
|
||||
logger.info("Waiting for other threads shuts down...")
|
||||
if args.debug:
|
||||
sigusr1handler(0, None)
|
||||
sigusr1handler()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import asyncio
|
||||
from datetime import datetime, timezone
|
||||
import logging
|
||||
from multiprocessing import JoinableQueue
|
||||
|
@ -40,7 +41,7 @@ class Bot(threading.Thread):
|
|||
"""Class containing the bot context and ensuring key goals"""
|
||||
|
||||
def __init__(self, ip="127.0.0.1", modules_paths=list(),
|
||||
data_store=datastore.Abstract(), debug=False):
|
||||
data_store=datastore.Abstract(), debug=False, loop=None):
|
||||
"""Initialize the bot context
|
||||
|
||||
Keyword arguments:
|
||||
|
@ -59,6 +60,9 @@ class Bot(threading.Thread):
|
|||
self.debug = debug
|
||||
self.stop = None
|
||||
|
||||
#
|
||||
self.loop = loop if loop is not None else asyncio.get_event_loop()
|
||||
|
||||
# External IP for accessing this bot
|
||||
import ipaddress
|
||||
self.ip = ipaddress.ip_address(ip)
|
||||
|
@ -522,6 +526,9 @@ class Bot(threading.Thread):
|
|||
for cnsr in k:
|
||||
cnsr.stop = True
|
||||
|
||||
logger.info("Closing event loop")
|
||||
self.loop.stop()
|
||||
|
||||
if self.stop is False or sync_queue is not None:
|
||||
self.stop = True
|
||||
sync_act("end")
|
||||
|
|
Loading…
Reference in New Issue