aboutsummaryrefslogtreecommitdiff
path: root/src/IRCBot.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/IRCBot.py')
-rw-r--r--src/IRCBot.py60
1 files changed, 44 insertions, 16 deletions
diff --git a/src/IRCBot.py b/src/IRCBot.py
index df0b0540..8eb1873e 100644
--- a/src/IRCBot.py
+++ b/src/IRCBot.py
@@ -1,9 +1,10 @@
import enum, queue, os, queue, select, socket, sys, threading, time, traceback
import typing, uuid
from src import EventManager, Exports, IRCServer, Logging, ModuleManager
-from src import PollHook, Socket, Timers, utils
+from src import PollHook, PollSource, Socket, Timers, utils
-VERSION = "v1.12.0-rc1"
+with open("VERSION", "r") as version_file:
+ VERSION = "v%s" % version_file.read().strip()
SOURCE = "https://git.io/bitbot"
URL = "https://bitbot.dev"
@@ -68,10 +69,7 @@ class Bot(object):
self._read_thread = None
self._write_thread = None
- self._poll_timeouts = [] # typing.List[PollHook]
- self._poll_timeouts.append(self._timers)
- self._poll_timeouts.append(self.cache)
-
+ self._poll_timeouts = [] # typing.List[PollHook.PollHook]
self._poll_timeouts.append(ListLambdaPollHook(
lambda: self.servers.values(),
lambda server: server.until_read_timeout()))
@@ -83,6 +81,13 @@ class Bot(object):
self._poll_timeouts.append(ListLambdaPollHook(
lambda: self.servers.values(), self._throttle_timeout))
+ self._poll_sources = [] # typing.List[PollSource.PollSource]
+
+ def add_poll_hook(self, hook: PollHook.PollHook):
+ self._poll_timeouts.append(hook)
+ def add_poll_source(self, source: PollSource.PollSource):
+ self._poll_sources.append(source)
+
def _throttle_timeout(self, server: IRCServer.Server):
if server.socket.waiting_throttled_send():
return server.socket.send_throttle_timeout()
@@ -276,11 +281,6 @@ class Bot(object):
def _event_loop(self):
while self.running or not self._event_queue.empty():
- if not self.servers and self._event_queue.empty():
- self._kill()
- self.log.warn("No servers, exiting")
- break
-
try:
item = self._event_queue.get(block=True,
timeout=self.get_poll_timeout())
@@ -316,16 +316,24 @@ class Bot(object):
def _write_loop(self):
while self.running:
+ poll_sources = {}
with self._write_condition:
- writeable = False
+ fds = []
for fd, server in self.servers.items():
if server.socket.waiting_immediate_send():
- self._write_poll.register(fd, select.POLLOUT)
- writeable = True
+ fds.append(fd)
+
+ for poll_source in self._poll_sources:
+ for fileno in poll_source.get_writables():
+ poll_sources[fileno] = poll_source
+ fds.append(fileno)
- if not writeable:
+ if not fds:
self._write_condition.wait()
continue
+ else:
+ for fd in fds:
+ self._write_poll.register(fd, select.POLLOUT)
events = self._write_poll.poll()
@@ -344,9 +352,25 @@ class Bot(object):
event_item = TriggerEvent(TriggerEventType.Action,
self._post_send_factory(server, lines))
self._event_queue.put(event_item)
+ elif fd in poll_sources:
+ poll_sources[fd].is_writeable(fd)
def _read_loop(self):
+ poll_sources = {}
while self.running:
+ new_poll_sources = {}
+ for poll_source in self._poll_sources:
+ for fileno in poll_source.get_readables():
+ new_poll_sources[fileno] = poll_source
+ for fileno in new_poll_sources:
+ if not fileno in poll_sources:
+ poll_sources[fileno] = new_poll_sources[fileno]
+ self._read_poll.register(fileno, select.POLLIN)
+ for fileno in list(poll_sources.keys()):
+ if not fileno in new_poll_sources:
+ del poll_sources[fileno]
+ self._read_poll.unregister(fileno)
+
events = self._read_poll.poll()
for fd, event in events:
@@ -355,6 +379,9 @@ class Bot(object):
with self._rtrigger_lock:
self._rtrigger_server.recv(1024)
self._rtriggered = False
+ elif fd in poll_sources:
+ poll_sources[fd].is_readable(fd)
+ self.trigger_write()
else:
if not fd in self.servers:
self._read_poll.unregister(fd)
@@ -376,7 +403,8 @@ class Bot(object):
def _check(self):
for poll_timeout in self._poll_timeouts:
- poll_timeout.call()
+ if poll_timeout.next() == 0:
+ poll_timeout.call()
throttle_filled = False
for server in list(self.servers.values()):