Grab response from functions asked to be executed on the main thread and feed

them back to the callers, allowing rest_api.py to take the main thread while
it's waiting for the response to give back to the requesting client
This commit is contained in:
jesopo 2018-11-27 14:25:12 +00:00
parent 00d4b9c73f
commit d13a5069e3
4 changed files with 30 additions and 18 deletions

View file

@ -86,16 +86,13 @@ class Module(ModuleManager.BaseModule):
for server, channel in targets: for server, channel in targets:
for output in outputs: for output in outputs:
output = "(%s) %s" % (full_name, output) output = "(%s) %s" % (full_name, output)
trigger = self._make_trigger(channel, server, output) self.events.on("send.stdout").call(target=channel,
self.bot.trigger(trigger) module_name="Github", server=server, message=line,
hide_prefix=channel.get_setting(
"github-hide-prefix", False))
return True return True
def _make_trigger(self, channel, server, line):
return lambda: self.events.on("send.stdout").call(target=channel,
module_name="Github", server=server, message=line,
hide_prefix=channel.get_setting("github-hide-prefix", False))
def _change_count(self, n, symbol, color): def _change_count(self, n, symbol, color):
return utils.irc.color("%s%d" % (symbol, n), color)+utils.irc.bold("") return utils.irc.color("%s%d" % (symbol, n), color)+utils.irc.bold("")
def _added(self, n): def _added(self, n):

View file

@ -30,9 +30,10 @@ class Handler(http.server.BaseHTTPRequestHandler):
if path.startswith("/api/"): if path.startswith("/api/"):
event_response = None event_response = None
try: try:
event_response = _events.on("api").on(method).on( event_response = _bot.trigger(lambda:
_events.on("api").on(method).on(
endpoint).call_unsafe_for_result(params=params, endpoint).call_unsafe_for_result(params=params,
path=args, data=data, headers=dict(self.headers)) path=args, data=data, headers=dict(self.headers)))
except Exception as e: except Exception as e:
_log.error("failed to call API endpoint \"%s\"", _log.error("failed to call API endpoint \"%s\"",
[path], exc_info=True) [path], exc_info=True)

View file

@ -11,7 +11,10 @@ class Module(ModuleManager.BaseModule):
def SIGINT(self, signum, frame): def SIGINT(self, signum, frame):
print() print()
self.events.on("signal.interrupt").call(signum=signum, frame=frame) self.bot.trigger(lambda: self._kill(signum))
def _kill(self, signum):
self.events.on("signal.interrupt").call(signum=signum)
for server in self.bot.servers.values(): for server in self.bot.servers.values():
reason = "Leaving" reason = "Leaving"
@ -19,7 +22,6 @@ class Module(ModuleManager.BaseModule):
reason = self.events.on("get.quit-quote" reason = self.events.on("get.quit-quote"
).call_for_result(default=reason) ).call_for_result(default=reason)
server.send_quit(reason) server.send_quit(reason)
self.bot.trigger()
self.events.on("writebuffer.empty").hook( self.events.on("writebuffer.empty").hook(
lambda event: self.bot.disconnect(event["server"])) lambda event: self.bot.disconnect(event["server"]))

View file

@ -1,4 +1,4 @@
import os, select, socket, sys, threading, time, traceback, typing, uuid import queue, os, select, socket, sys, threading, time, traceback, typing, uuid
from src import EventManager, Exports, IRCServer, Logging, ModuleManager from src import EventManager, Exports, IRCServer, Logging, ModuleManager
from src import Socket, utils from src import Socket, utils
@ -29,12 +29,23 @@ class Bot(object):
self._trigger_functions = [] self._trigger_functions = []
self._events.on("timer.reconnect").hook(self._timed_reconnect) self._events.on("timer.reconnect").hook(self._timed_reconnect)
def trigger(self, func: typing.Callable[[], typing.Any]=None): def trigger(self,
func: typing.Optional[typing.Callable[[], typing.Any]]=None):
func = func or (lambda: None)
if threading.current_thread() is threading.main_thread():
returned = func()
self._trigger_client.send(b"TRIGGER")
return returned
self.lock.acquire() self.lock.acquire()
if func:
self._trigger_functions.append(func) func_queue = queue.Queue(1)
self._trigger_client.send(b"TRIGGER") self._trigger_functions.append([func, func_queue])
self.lock.release() self.lock.release()
self._trigger_client.send(b"TRIGGER")
return func_queue.get(True)
def add_server(self, server_id: int, connect: bool = True, def add_server(self, server_id: int, connect: bool = True,
connection_params: typing.Optional[ connection_params: typing.Optional[
@ -165,8 +176,9 @@ class Bot(object):
self._timers.call() self._timers.call()
self.cache.expire() self.cache.expire()
for func in self._trigger_functions: for func, func_queue in self._trigger_functions:
func() returned = func()
func_queue.put(returned)
self._trigger_functions.clear() self._trigger_functions.clear()
for fd, event in events: for fd, event in events: