Skip to content

Commit c16ac9e

Browse files
committed
Adjust join rate limiting, add retain_cache
Join channels rate limiting has been adjusted to fix 20+ initial_channels retain_cache has also been added as a kwarg to Client
1 parent 3fb11aa commit c16ac9e

File tree

4 files changed

+21
-6
lines changed

4 files changed

+21
-6
lines changed

docs/changelog.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ Massive documentation updates
77
- TwitchIO
88
- Removed unexpected loop termination from `WSConnection._close()`
99
- Fix bug where # prefixed channel names and capitals in initial_channels would not trigger :func:`twitchio.Client.event_ready`
10+
- Adjusted join channel rate limit handling
11+
- Added `retain_cache` kwarg to Client and Bot
1012
- :func:`User.create_clip` has been fixed by converting bool to string in http request
1113
- Poll endpoints added :func:`User.fetch_polls` :func:`User.create_poll` and :func:`User.end_poll`
1214
- :func:`Client.fetch_cheermotes` color attribute corrected

twitchio/client.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ class Client:
6060
The event loop the client will use to run.
6161
heartbeat: Optional[float]
6262
An optional float in seconds to send a PING message to the server. Defaults to 30.0.
63+
retain_cache: Optional[bool]
64+
An optional bool that will retain the cache if PART is received from websocket when True.
65+
It will still remove from cache if part_channels is manually called. Defaults to False.
6366
6467
Attributes
6568
------------
@@ -75,6 +78,7 @@ def __init__(
7578
initial_channels: Union[list, tuple, Callable] = None,
7679
loop: asyncio.AbstractEventLoop = None,
7780
heartbeat: Optional[float] = 30.0,
81+
retain_cache: Optional[bool] = False,
7882
):
7983

8084
self.loop: asyncio.AbstractEventLoop = loop or asyncio.get_event_loop()
@@ -89,6 +93,7 @@ def __init__(
8993
loop=self.loop,
9094
initial_channels=initial_channels,
9195
heartbeat=heartbeat,
96+
retain_cache=retain_cache,
9297
)
9398

9499
self._events = {}

twitchio/ext/commands/bot.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,15 @@ def __init__(
5555
client_secret: str = None,
5656
initial_channels: Union[list, tuple, Callable] = None,
5757
heartbeat: Optional[float] = 30.0,
58+
retain_cache: Optional[bool] = False,
5859
**kwargs,
5960
):
6061
super().__init__(
61-
token=token, client_secret=client_secret, initial_channels=initial_channels, heartbeat=heartbeat
62+
token=token,
63+
client_secret=client_secret,
64+
initial_channels=initial_channels,
65+
heartbeat=heartbeat,
66+
retain_cache = retain_cache,
6267
)
6368

6469
self._prefix = prefix

twitchio/websocket.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ def __init__(
6060
token: str = None,
6161
modes: tuple = None,
6262
initial_channels: List[str] = None,
63+
retain_cache: Optional[bool] = False,
6364
):
6465
self._loop = loop
6566
self._backoff = ExponentialBackoff()
@@ -94,6 +95,7 @@ def __init__(
9495
self._token = token
9596
self.modes = modes or ("commands", "tags", "membership")
9697
self._initial_channels = initial_channels or []
98+
self._retain_cache = retain_cache
9799

98100
if callable(self._initial_channels):
99101
_temp_initial_channels = self._initial_channels()
@@ -261,6 +263,8 @@ async def part_channels(self, *channels: str):
261263
for channel in channels:
262264
channel = re.sub("[#]", "", channel).lower()
263265
await self.send(f"PART #{channel}\r\n")
266+
if self._retain_cache:
267+
self._cache.pop(channel, None)
264268

265269
async def join_channels(self, *channels: str):
266270
"""|coro|
@@ -276,11 +280,10 @@ async def join_channels(self, *channels: str):
276280
for channel in channels:
277281
if self._join_handle < time.time(): # Handle is less than the current time
278282
self._join_tick = 20 # So lets start a new rate limit bucket..
279-
self._join_handle = time.time() + 10 # Set the handle timeout time
283+
self._join_handle = time.time() + 11 # Set the handle timeout time
280284

281285
if self._join_tick == 0: # We have exhausted the bucket, wait so we can make a new one...
282286
await asyncio.sleep(self._join_handle - time.time())
283-
continue
284287

285288
asyncio.create_task(self._join_channel(channel))
286289
self._join_tick -= 1
@@ -294,7 +297,7 @@ async def _join_channel(self, entry):
294297

295298
async def _join_future_handle(self, fut: asyncio.Future, channel: str):
296299
try:
297-
await asyncio.wait_for(fut, timeout=10)
300+
await asyncio.wait_for(fut, timeout=11)
298301
except asyncio.TimeoutError:
299302
log.error(f'The channel "{channel}" was unable to be joined. Check the channel is valid.')
300303
self._join_pending.pop(channel)
@@ -386,8 +389,8 @@ async def _part(self, parsed): # TODO
386389
pass
387390
else:
388391
self._join_pending.pop(channel)
389-
390-
self._cache.pop(channel, None)
392+
if not self._retain_cache:
393+
self._cache.pop(channel, None)
391394

392395
channel = Channel(name=channel, websocket=self)
393396
user = Chatter(name=parsed["user"], bot=self._client, websocket=self, channel=channel, tags=parsed["badges"])

0 commit comments

Comments
 (0)