Ejemplo n.º 1
0
async def create_timer(bot: commands.Bot, expires_at: datetime.datetime,
                       event_type: str, *args, **kwargs) -> Timer:
    now = datetime.datetime.utcnow()
    timer = Timer.temporary(now, expires_at, event_type, *args, **kwargs)

    delta = (expires_at - now).total_seconds()
    if delta <= 60:
        bot.loop.create_task(timer.call(bot))
        return timer

    record = await Timers.insert(returning=Timers.id,
                                 expires_at=expires_at,
                                 event_type=event_type,
                                 data=dict(args=args, kwargs=kwargs))

    # Set the timer's ID
    timer.id = record[0]

    # Only set the data check if the timer can be waited for
    if delta <= discord.utils.MAX_ASYNCIO_SECONDS:
        bot._active_timer.set()

    # Check if the timer is earlier than the currently set timer
    if bot._current_timer is not None and expires_at < bot._current_timer.expires_at:
        bot._timer_task.cancel()
        bot._timer_task = bot.loop.create_task(dispatch_timers(bot))

    return timer
Ejemplo n.º 2
0
async def dispatch_timers(bot: commands.Bot):
    # Wait until bot is ready
    await bot.wait_until_ready()

    try:
        while not bot.is_closed():
            # fetch the next timer from the database
            timer = bot._current_timer = await _wait_for_active(bot, days=40)
            now = datetime.datetime.utcnow()

            # if timer has not yet expired
            if timer.expires_at >= now:
                await discord.utils.sleep_until(timer.expires_at)

            await timer.call(bot)

    except asyncio.CancelledError:
        pass
    except (OSError, discord.ConnectionClosed,
            asyncpg.PostgresConnectionError):
        bot._timer_task.cancel()
        bot._timer_task = bot.loop.create_task(dispatch_timers(bot))
    except Exception as exc:
        print('Unhandled exception in internal timer task', file=sys.stderr)
        traceback.print_exception(type(exc),
                                  exc,
                                  exc.__traceback__,
                                  file=sys.stderr)
Ejemplo n.º 3
0
async def delete_timer(bot: commands.Bot, record: asyncpg.Record, *,
                       connection: asyncpg.Connection):
    await Timers.delete(id=record['id'])

    # if the current timer is being deleted skip it
    if bot._current_timer and bot._current_timer.id == record['id']:
        bot._timer_task.cancel()
        bot._timer_task = bot.loop.create_task(dispatch_timers(bot))