Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: ensure next_fire in TimeTrigger returns proper next time #1575

Merged
merged 3 commits into from
Nov 30, 2023

Conversation

AstreaTSS
Copy link
Member

Pull Request Type

  • Feature addition
  • Bugfix
  • Documentation update
  • Code refactor
  • Tests improvement
  • CI/CD pipeline enhancement
  • Other: [Replace with a description]

Description

This one's a bit weird, so I'll explain it through an example.

Let's say, on a bot's device, the time is currently 11:00 PM (23:00) EST on 2023-11-27 (YYYY-MM-DD). EST has a time difference of -5 hours from UTC, making this 4:00 AM UTC on the next day, 2023-11-28. Now, say, we create a task that looks like so:

@interactions.Task.create(interactions.TimeTrigger(3, 59, 00, utc=True))
async def test():
    print("test")

Naturally, this should result in the task, if started, to not trigger until 10:59 PM (22:59) EST, or 3:59 AM UTC, the next day (2023-11-28). However, this will not happen - what will happen is that the console will have an endless spam of test until midnight EST. But why is this the case?

The offender of this issue is in TimeTrigger's next_fire, so let's break it down.

def next_fire(self) -> datetime | None:
    now = datetime.now()
    target = datetime(
        now.year,
        now.month,
        now.day,
        self.target_time[0],
        self.target_time[1],
        self.target_time[2],
        tzinfo=self.tz,
    )
    if target.tzinfo == timezone.utc:
        target = target.astimezone(now.tzinfo)
        target = target.replace(tzinfo=None)

    if target <= self.last_call_time:
        target += timedelta(days=1)
    return target

On the first run of this program, now is 11:00 PM (23:00) EST on 2023-11-27. Thus, target is 3:59 AM UTC on 2023-11-27. Because the target's timezone is UTC, target gets converted into the equivalent time in (well, in this case) EST - 10:59 PM (22:59) EST on 2023-11-26.

When first starting the bot, we can assume self.last_call_time is essentially now - it'll maybe be a couple of seconds behind, but that doesn't matter. Now, our target is indeed less than the time it is right now - as an attempt to fix this, the code adds a day to target, making it 10:59 PM (22:59) EST on 2023-11-27.

Note, though, that the current time is 11:00 PM (23:00) EST on 2023-11-27, meaning the target is still behind now when that should never happen, breaking the rest of the task's code's assumptions and causing that loop.

Now, this all happens because target, when being converted from UTC to local/native time, goes back a day, when the code incorrectly assumes that it'll stay on the same day. This PR fixes that by ensuring that the new target, after the time conversions, is set back to the current date as specified by now.

Changes

  • Ensure target has the same date (though not time) as now in TimeTrigger's next_fire().

Related Issues

Test Scenarios

See the description.

Python Compatibility

  • I've ensured my code works on Python 3.10.x
  • I've ensured my code works on Python 3.11.x

Checklist

  • I've run the pre-commit code linter over all edited files
  • I've tested my changes on supported Python versions
  • I've added tests for my code, if applicable
  • I've updated / added documentation, where applicable

Copy link
Member

@silasary silasary left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, fun. Thanks for looking into this

@LordOfPolls LordOfPolls merged commit 15a72cd into interactions-py:unstable Nov 30, 2023
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants