diff options
| author | 2026-05-01 14:56:53 +0000 | |
|---|---|---|
| committer | 2026-05-01 14:56:53 +0000 | |
| commit | a0ce214430138ddd93dc36c56e4bec533c92d195 (patch) | |
| tree | 11dd3ee1bcb724f7f473bab61f334d2ba2ab9963 /http2irc.py | |
| parent | Allow having certain irc config changes without reconnect (diff) | |
Allow setting a global message ratelimit
This allows configuring a http2irc instance to have a higher global
message sending rate limit different from the default hard-coded rate of
1 message / second, whilst keeping backwards compatibility by keeping
default value being the hard-coded one.
In addition if the rate limit is set to 0, which can be done live, the
bot will stop sending queued messages whilst keeping the IRC connection
alive.
Diffstat (limited to 'http2irc.py')
| -rw-r--r-- | http2irc.py | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/http2irc.py b/http2irc.py index a73f23d..57c66ac 100644 --- a/http2irc.py +++ b/http2irc.py @@ -104,7 +104,7 @@ class Config(dict): except (ValueError, AssertionError) as e: raise InvalidConfig('Invalid log format: parsing failed') from e if 'irc' in obj: - if any(x not in ('host', 'port', 'ssl', 'family', 'nick', 'real', 'certfile', 'certkeyfile') for x in obj['irc']): + if any(x not in ('host', 'port', 'ssl', 'family', 'nick', 'real', 'certfile', 'certkeyfile', 'sendratelimit') for x in obj['irc']): raise InvalidConfig('Unknown key found in irc section') if 'host' in obj['irc'] and not isinstance(obj['irc']['host'], str): #TODO: Check whether it's a valid hostname raise InvalidConfig('Invalid IRC host') @@ -124,6 +124,11 @@ class Config(dict): raise InvalidConfig('Invalid IRC nick: contains illegal characters') if len(IRCClientProtocol.nick_command(obj['irc']['nick'])) > 510: raise InvalidConfig('Invalid IRC nick: NICK command too long') + if 'sendratelimit' in obj['irc']: + if not type(obj['irc']['sendratelimit']) in [float, int]: + raise InvalidConfig('Invalid ratelimit, must be a float or a integer') + if obj['irc']['sendratelimit'] < 0: + raise InvalidConfig('Ratelimit must be positive') if 'real' in obj['irc'] and not isinstance(obj['irc']['real'], str): raise InvalidConfig('Invalid IRC realname') if len(IRCClientProtocol.user_command(obj['irc']['nick'], obj['irc']['real'])) > 510: @@ -225,7 +230,7 @@ class Config(dict): # Default values finalObj = { 'logging': {'level': 'INFO', 'format': '{asctime} {levelname} {name} {message}'}, - 'irc': {'host': 'irc.hackint.org', 'port': 6697, 'ssl': 'yes', 'family': 0, 'nick': 'h2ibot', 'real': 'I am an http2irc bot.', 'certfile': None, 'certkeyfile': None}, + 'irc': {'host': 'irc.hackint.org', 'port': 6697, 'ssl': 'yes', 'family': 0, 'nick': 'h2ibot', 'real': 'I am an http2irc bot.', 'certfile': None, 'certkeyfile': None, 'sendratelimit': 1 }, 'web': {'host': '127.0.0.1', 'port': 8080, 'maxrequestsize': 1048576}, 'maps': {} } @@ -484,11 +489,16 @@ class IRCClientProtocol(asyncio.Protocol): data = t.result() self.logger.debug(f'Got {data!r} from send queue') now = time.time() - if self.lastSentTime is not None and now - self.lastSentTime < 1: - self.logger.debug(f'Rate limited') + if self.config['irc']['sendratelimit'] == 0: + self.logger.debug(f'Rate limited, not sending messages for now.') await wait_cancel_pending({asyncio.create_task(self.connectionClosedEvent.wait())}, timeout = self.lastSentTime + 1 - now) if self.connectionClosedEvent.is_set(): break + if (self.lastSentTime is not None and now - self.lastSentTime < 1/self.config['irc']['sendratelimit']) or self.config['irc']['sendratelimit'] == 0: + self.logger.debug(f'Rate limited') + await wait_cancel_pending({asyncio.create_task(self.connectionClosedEvent.wait())}, timeout = self.lastSentTime + 1/self.config['irc']['sendratelimit'] - now) + if self.connectionClosedEvent.is_set(): + break time_ = self._direct_send(data) if self.lastSentTime is not None: self.lastSentTime = time_ |
