-
Notifications
You must be signed in to change notification settings - Fork 3k
events: Introduce API to query how much time is left for delayed event #6901
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
Conversation
Interesting interesting interesting. The implementation looks great (probably the best pr I've seen in a while). But I'm concerned this will encourage users to write racey code. As soon as you call equeue_timeleft, the result could be out of date. For a similar reason we haven't provided a "has my event executed?" function, which this indirectly provides. What is this function used for? Is it something that could be handled outside of the EventQueue class? Looking at the LoraWAN pr I'm not sure this is used. |
In LoRa use case we use EventQueue to delay an event when TX is limited by a duty cycle. When duty cycle limits the TX, we calculate a backoff time when next TX is possible and it can be something between seconds to few minutes. User might want to know when this next TX is possible so in our case it is the same as the time when this delayed event is going to be dispatched. |
This isn't necessary, as someone can always monitor it themselves (at least if they're not using The race is fundamentally the same as |
Hmmm, Ok, you've convinced me. Lets try to get this guy in 👍 @kjbracey-arm, cancel doesn't tell you if it cancelled an event or not, after cancel you can just assume the event will not execute. |
events/EventQueue.h
Outdated
* | ||
* @return Remaining time in milliseconds or | ||
* 0 if event is already due to be dispatched or | ||
* -1 if invalid event id. |
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.
Do you think we should actually return 0 for an invalid id? Otherwise, when exactly this value changes from 0 -> -1 isn't well defined.
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 was thinking that return value of invalid id should be somehow separated from 0 which is a valid value.
But actually the "invalid event id" seems to be a little problematic. Checking id 0 is clear but a random id is not. I don't think this check works properly (I just followed how cancel was implemented):
if (e->id == id >> q->npw2)
Just a quick test with id 99 gives following:
e->id = 0, id = 99, q->npw2 = 10, id >> q->npw2 = 0
so it is comparing 0 == 0 and therefore starts calculating diff from an invalid event.
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.
well, same with cancel, the user isn't allowed to pass an arbitrary int, only int ids given from a post function or the NULL event id 0.
For 99, the lookup in the array will point to arbitrary memory.
/morph build |
So |
Can you though? The event could have just started executing the event, but not reached the point where the user hits its own state mutex. I think you need some protection to be sure:
Similar, but not quite so scary. Stop on a thread could kill you almost anywhere while executing - cancel on an event can't stop you mid-event.
And the detection of invalid IDs is not reliable - it's just an emergency backstop, I guess? So, what's the correct usage semantics for this and cancel? I think it has to be legal to call either while the event is still executing - you can't totally avoid that, as per the illustration above. The event code can't change state to prevent it until part-way through. But it's illegal to call it after the event has executed, right? Completion of the event execution must be assumed to invalidate the ID. Should we be asserting in cases where we can confirm invalidity? I'd suggest yes. And maybe we don't define the return code for "invalid event ID" - it's undefined behaviour, asserting in debug builds. |
Build : SUCCESSBuild number : 2040 Triggering tests/morph test |
Test : SUCCESSBuild number : 1856 |
Exporter Build : SUCCESSBuild number : 1689 |
Ah you're right, although you do get the garauntee if you call cancel on the same thread of dispatch. Note that canceling an event inside itself is valuable if the event is periodic. I keep going back and forth, but now I'm thinking sticking with -1 is a good idea. For the timing functions it represents an "infinite" timeout. And we would have the same race condition with periodic events flipping from 0 -> next timeout. |
@SenRamakri @pan- Thoughts? |
Could this go through after Chris's review ? This is the baseline for another pending PR. |
If user has initiated a delayed event (either with call_in or call_every), user might need to know how much time is left until the event is due to be dispatched. Added time_left() function can be used to get the remaining time.
Updated the descriptions for cancel() and time_left() about invalid event id and updated the test to check time_left when event is executing. |
/morph build |
Build : SUCCESSBuild number : 2072 Triggering tests/morph test |
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.
Good job 👍
Test : SUCCESSBuild number : 1884 |
Exporter Build : SUCCESSBuild number : 1719 |
@cmonr Could this go in ? Other stuff in the pipeline is clogged. |
Description
If user has initiated a delayed event (either with call_in or call_every),
user might need to know how much time is left until the event is
due to be dispatched.
Added time_left() function can be used to get the remaining time.
Pull request type