1
0
Fork 0

Start using asyncio for signals

This commit is contained in:
nemunaire 2017-07-18 07:18:06 +02:00 committed by nemunaire
parent f26d95963e
commit c6b5aab917
3 changed files with 18 additions and 26 deletions

View File

@ -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).

View File

@ -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)

View File

@ -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")