-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Augment gen_server
timeout handling
#9287
base: master
Are you sure you want to change the base?
Conversation
CT Test Results 2 files 96 suites 1h 8m 11s ⏱️ Results for commit 6c2ef49. ♻️ This comment has been updated with latest results. To speed up review, make sure that you have read Contributing to Erlang/OTP and that all checks pass. See the TESTING and DEVELOPMENT HowTo guides for details about how to run test locally. Artifacts// Erlang/OTP Github Action Bot |
1c31fe6
to
9789858
Compare
Co-authored-by: Jan Uhlig <[email protected]>
9789858
to
6c2ef49
Compare
Hi! You point out a bunch of design quirks/flaws with the
But this PR only addresses one problem, namely attaching supplementary data to the time-out. The PR's suggested form for the new time-out is So that means that if this PR is accepted we have another flawed time-out in I lean towards not augmenting the |
@@ -2264,6 +2283,15 @@ loop(Parent, Name, State, CbCache, infinity, HibernateAfterTimeout, Debug) -> | |||
loop(Parent, Name, State, CbCache, hibernate, HibernateAfterTimeout, Debug) | |||
end; | |||
|
|||
loop(Parent, Name, State, CbCache, {timeout, Time, TimeoutMsg} = Timeout, HibernateAfterTimeout, Debug) -> |
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.
Perhaps Time =:= infinity
should be handled here instead of in handle_msg/7
, handle_common_reply/8
below, and two places above; init_it/5
and enter_loop/5
(missing).
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.
TBH, I had it this way before, then thought having it in the handle_msg
and friends functions would be better. But you're right, especially when combined with what @michalmuskala suggested. I'll change it back later.
Then again, this particular enhancement doesn't change any of the good qualities about the So the question is how much better would the |
I mostly agree with what Raimo said, the only thing I would consider changing, if this is going forward would be to have the message delivered be just |
I know, but I don't think that much can be done about those =( In any case, I wasn't trying to with this PR ;)
To be sure, I took care not to change anything that would affect the current way how timeouts work in
Excellent point, this is much better. Thanks for the suggestion 🤗 I think I'll just let this discussion run for a while longer before making any changes to it, though 🙂 |
@Maria-12648430 wrote:
But in a way it does. If we would like to introduce the For instance; we could instead of this minimal suggestion, re-use that Timeout loop variable in |
@RaimoNiskanen ok, maybe I got you a bit wrong in the beginning. So I understand that you are not against adding the functionality this PR provides, but that you would like it to also address the other (at least two) quirks you mentioned, ie that adding only the ability to transmit timeout data falls short and may even get in the way of adressing the other issues later? Tackling the other issues would mean changing That is, unless you say that it's unlikely to be accepted, then of course we will save ourselves the trouble 😜 |
|
@Maria-12648430 Precisely. I would like that when adding a time-out that looks like in I would also like to not slow down I also would like that all quirks are addressed, not just the two I mentioned. But I guess it is impossible to completely fix fakeability without adding a new So far I have not gotten any opinions from the rest of the team, I will have to get back to you about if it would be likely to be accepted... |
Ok, well then... what are the others? 😅 |
Indeed. In
Ok, keep us in the loop ➰ 🙂 🤗 |
Hmmm, I had the feeling you mentioned a few, but it seems you mentioned supplementary data, fakeability, and that the
So, as you point out, by enabling arbitrary time-out messages according to your suggestion, the two quirks I brought up would be the only remaining, and they are a consequence of the current time-outs not being delayed process messages. |
@RaimoNiskanen say, is there anything speaking against carrying some of the I can go with that if that is better for some reason, but it makes the going a little tough, and a record would at least feel a lot better XD |
It is in general beneficial to reduce the number of loop arguments, because of the BEAM calling convention. For example in So keeping
This is the kind of things I looked at when optimizing For example I see that the argument order differs between Maybe helpers like One would have to look at the generated BEAM assembly to see these undesired register move clusters along the hot path that may be possible to avoid. Finding a balance between keeping volatile state in argument registers versus avoiding lots of register shuffling is the game. |
While working on something entirely different, it ocurred to me that timeouts in
gen_server
have some drawbacks and pitfalls.When the return of
gen_server:init
or ahandle_*
callback contains a timeout, the next iteration will wait for a message for that time, and if no message arrives, instantly callhandle_info
with the messagetimeout
(ie, not sending itself atimeout
message).For one, this convolution of
handle_info
for message and timeout handling makes it impossible to distinguish an actual timeout from the messagetimeout
having been received. This means that you either have to make sure that, if you are using timeouts, such a message will not be sent to yourgen_server
implementation, or live with possible premature "fake" timeouts.For another, it is very inconvenient if one wants to enricht the timeout with some supplementary data. This is only possible by putting it somewhere in the state, and must likely be removed from the state again if a message arrives before the timeout occurs.
Another option is to manually maintain timers, which is also inconvenient and requires quite some boilerplate code.
The changes in this PR allow
init
andhandle_*
callbacks to return the tuple{timeout, Time, TimeoutMessage}
. In case a timeout occurs,handle_info
will instantly be called with the message{timeout, TimeoutMessage}
.There are no tests or documentation yet, I first want to see if there is any interest in this feature at all.