Skip to content

Commit

Permalink
Redesign of PaginatorInterface update system
Browse files Browse the repository at this point in the history
  • Loading branch information
Gorialis committed Feb 26, 2021
1 parent 3a02799 commit 3389383
Showing 1 changed file with 56 additions and 50 deletions.
106 changes: 56 additions & 50 deletions jishaku/paginators.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ def __init__(self, bot: commands.Bot, paginator: commands.Paginator, **kwargs):

self.task: asyncio.Task = None
self.send_lock: asyncio.Event = asyncio.Event()
self.update_lock: asyncio.Lock = asyncio.Semaphore(value=kwargs.pop('update_max', 2))

self.close_exception: Exception = None

Expand Down Expand Up @@ -185,7 +184,7 @@ async def add_line(self, *args, **kwargs):
if display_page + 1 == page_count:
# To keep position fixed on the end, update position to new last page and update message.
self._display_page = new_page_count
self.bot.loop.create_task(self.update())
self.send_lock.set()

async def send_to(self, destination: discord.abc.Messageable):
"""
Expand Down Expand Up @@ -265,28 +264,62 @@ def check(payload: discord.RawReactionActionEvent):

return all(tests)

try:
while not self.bot.is_closed():
payload = await self.bot.wait_for('raw_reaction_add', check=check, timeout=self.timeout)
task_list = [
self.bot.loop.create_task(coro) for coro in {
self.bot.wait_for('raw_reaction_add', check=check),
self.bot.wait_for('raw_reaction_remove', check=check),
self.send_lock.wait()
}
]

emoji = payload.emoji
if isinstance(emoji, discord.PartialEmoji) and emoji.is_unicode_emoji():
emoji = emoji.name
try:
last_kwargs = None

if emoji == close:
await self.message.delete()
return
while not self.bot.is_closed():
done, _ = await asyncio.wait(task_list, timeout=self.timeout, return_when=asyncio.FIRST_COMPLETED)

for task in done:
task_list.remove(task)
payload = task.result()

if isinstance(payload, discord.RawReactionActionEvent):
emoji = payload.emoji
if isinstance(emoji, discord.PartialEmoji) and emoji.is_unicode_emoji():
emoji = emoji.name

if emoji == close:
await self.message.delete()
return

if emoji == start:
self._display_page = 0
elif emoji == end:
self._display_page = self.page_count - 1
elif emoji == back:
self._display_page -= 1
elif emoji == forward:
self._display_page += 1

if payload.event_type == 'REACTION_ADD':
task_list.append(self.bot.loop.create_task(
self.bot.wait_for('raw_reaction_add', check=check)
))
elif payload.event_type == 'REACTION_REMOVE':
task_list.append(self.bot.loop.create_task(
self.bot.wait_for('raw_reaction_remove', check=check)
))
else:
# Send lock was released
task_list.append(self.bot.loop.create_task(self.send_lock.wait()))

if emoji == start:
self._display_page = 0
elif emoji == end:
self._display_page = self.page_count - 1
elif emoji == back:
self._display_page -= 1
elif emoji == forward:
self._display_page += 1
if self.send_kwargs != last_kwargs:
try:
await self.message.edit(**self.send_kwargs)
except discord.NotFound:
# something terrible has happened
return

self.bot.loop.create_task(self.update())
last_kwargs = self.send_kwargs

try:
await self.message.remove_reaction(payload.emoji, discord.Object(id=payload.user_id))
Expand All @@ -309,36 +342,9 @@ def check(payload: discord.RawReactionActionEvent):
except (discord.Forbidden, discord.NotFound):
pass

async def update(self):
"""
Updates this interface's messages with the latest data.
"""

if self.update_lock.locked():
return

await self.send_lock.wait()

async with self.update_lock:
if self.update_lock.locked():
# if this engagement has caused the semaphore to exhaust,
# we are overloaded and need to calm down.
await asyncio.sleep(1)

if not self.message:
# too fast, stagger so this update gets through
await asyncio.sleep(0.5)

if not self.sent_page_reactions and self.page_count > 1:
self.bot.loop.create_task(self.send_all_reactions())
self.sent_page_reactions = True # don't spawn any more tasks

try:
await self.message.edit(**self.send_kwargs)
except discord.NotFound:
# something terrible has happened
if self.task:
self.task.cancel()
finally:
for task in task_list:
task.cancel()


class PaginatorEmbedInterface(PaginatorInterface):
Expand Down

0 comments on commit 3389383

Please sign in to comment.