-
-
Notifications
You must be signed in to change notification settings - Fork 405
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
coretasks: Periodically send WHO to keep user information up-to-date #1664
Conversation
Not a bad idea. We should definitely put some thought into the interval duration, based on how other bots and clients behave. More importantly, Sopel shouldn't do any Lines 822 to 831 in 9340c67
Our |
I agree. This PR should be updated to use a reasonable interval, and to avoid sending the WHO request if the |
As far as the interval duration itself, I've done a small survey of clients I use or have used in the past:
HexChat's is probably the nicest approach, but also the most complex to implement and the most likely to have outdated information (since as the bot's channel count grows, it takes longer between updates of a given channel's status information). I'd say KVIrc's approach is the next-nicest. |
The KiwiIRC client looks to be the same as HexChat (which is what I based my 30 seconds on). I agree the KvIRC approach seems to make the most sense. I'll try to start taking a look at this tomorrow. |
Checks every 30 seconds to see if any channel's last WHO request was greater than 120 seconds ago, and initiates a request for the channel with the oldest previous request time. Does not issue more than one WHO request every 30 seconds. The Channel class in target.py was modified to provide a class attribute to track the last time a WHO request was issued for the channel.
Further to the discussion, I've included some additional logic around sending periodic This function checks every 30 seconds to see if any channel's last The Channel class in target.py was modified to provide a class attribute to track the last time a I have no idea why this would be causing one of the DuckDuckGo search engine tests to be failing under Python 2.7. I suspect that might be an unrelated issue? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the interval
approach, that's the right tool for the job. So, good work on that!
On the other hand, I feel like the code is a bit complicated to me, and I got confused with the timestamp manipulation. Using an integer can be a good idea, but it's not immediately clear why the magic number 1. I'd rather see None
keeping its semantic value of "not set yet" and datetime objects compared to each other, like this:
elapsed_time = datetime.today() - timedelta(seconds=120)
if channel.last_who is None or channel.last_who <= elapsed_time:
# request a who
Other small nitpicks are the usage of 1
as a default value while None
has a useful semantic value that is lost with that 1, making thing a bit confusing to me; and the very long name and the very long line that comes with it - nothing that can't be fixed.
Save last_who information as datetime value and use timedelta to calculate the time value used to trigger a new WHO request.
I tightened up (and simplified) the code a bit and got rid of the "arbitrary" comparison value. Also changed some of the variable names to more accurately reflect their purpose (and shorten them a bit). I think the logic is a bit clearer now. Is this more in line with what you were looking for? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aside from line-length (even I, usually laissez-faire about long lines, think these if
s are too long), I think the loop through all channels can be broken early if it's obvious that the bot has found a candidate that will not be replaced (e.g. upon finding a channel with last_who == None
).
It might also be easier to read the logic if you don't shy away from nesting if
/elif
/else
blocks. Often, that's clearer than this sort of and
/or
chaining with parenthesis groupings.
I have no idea why this would be causing one of the DuckDuckGo search engine tests to be failing under Python 2.7. I suspect that might be an unrelated issue?
It just happens sometimes for certain tests, usually from search.py
. We're still figuring out the best way to ignore or retry transient errors like that on Travis, since they do affect PR mergeability. Me kicking the failed test run manually usually fixes it.
@dgw, I've added the
I think the logic is still clear, but I'm biased because I developed it. 😉 I'm okay with it the way it is now (each test separate), or I can make these changes if you prefer. |
Ah! I like where you are going with that. Let me push that even further: who_trigger_interval = datetime.timedelta(seconds=120)
who_trigger_time = datetime.datetime.utcnow() - who_trigger_interval
selected_channel = None
for channel in bot.channels:
if channel.last_who is None:
# WHO was never sent yet to this channel: stop here
selected_channel = channel
break
if channel.last_who < who_trigger_time:
# this channel's last who request is the most outdated one at the moment
selected_channel = channel
who_trigger_time = channel.last_who
if selected_channel is not None:
# selected_channel's last who is either none or the oldest valid
_send_who(bot, selected_channel) The |
@Exirel, that suggestion is brilliant! I'll update the PR accordingly. |
Optimize the channel selection logic as suggested by Exirel. Add some comments to help explain / clarify the processing logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A tiny nitpick (if-conditions usually don't need parenthesis), and we are all good to go. This is a great feature, and I'm happy to see it ready so fast.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great iteration, everyone!
I usually prefer to squash the code-review stuff out of PRs before merging. But this time, the evolution of the feature is so clean compared to how it usually happens ("fix:" and "Update filename.py" commits scattered around) that I don't think we should bother squashing. @Exirel, agree?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Squash it or not, it's a 👍 🚢
Add an interval event to periodically issue a WHO request to keep user information up-to-date.
This provides part of the solution to Issue #1659 : User's "away" status always "None"