-
Notifications
You must be signed in to change notification settings - Fork 7
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
Feat/request cancel support #12
Conversation
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.
This approach works I think, left one comment on handling cancelled requests.
ector/src/actor.rs
Outdated
|
||
async fn handle_missed(&mut self) { | ||
while self.cancelled > 0 { | ||
self.reply_to.recv().await; |
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.
Would it be better to attempt draining the channel using try_recv()? Or do we always know that the other side will send the reply?
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 question, I didn't think of draining the channel. Thing is we might not receive the response associated with the right request.
Here's an example of what could happen
- Sender: Sends a request 1
- Actor: Starts handling request 1 but it takes some time
- Sender: Cancels request 1
- Sender: Sends request 2 (drains channel, but nothing in it yet)
- Actor: Completes request 1
- Sender: Receives response from request 1 instead of 2
We can either
- Always assume a response is sent back
- Or assume that is not the case and accept that we might receive the response from the previous request when doing cancellation
- Or have a way to let the
Request
struct know that request was cancelled and no send the response when the request was cancelled. Would probably be ideal but I don't know yet how we could implement this.
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.
@xgroleau I admit I totally forgot about this. I think it's ok to merge if you're happy with it the way it is.
37ecae3
to
a846a67
Compare
No worries, honestly I did too. I just completed the integration of the new changes in our code base, but I feel like the types and macro usage is starting to get in the way of readability a bit. I wonder if there would be a better way to handle this. Actual example in our codebase for spawning ONE actor. we probably have a dozen. let battery_monitoring = BatteryMonitoringActor::new(
comm_addr,
ector::request!(log_addr, Result<&'static Path, StorageError>), // Since it handles Requests
ector::request!(metrics_addr, Result<&'static Path, StorageError>), // Also here
gui_addr,
ector::request!(power_management_addr, BatteryState), // and here
);
ector::spawn_context!(
BATTERY_MONITORING_ACTOR,
med_spawner,
battery_monitoring_actor,
BatteryMonitoringHandler, // Type alias for the full type
battery_monitoring
); It does work, I just don't like the fact that I need to specify the return type of the If it's too much, we could make it "safe" by panicking if a request is dropped while it's ongoing to avoid writing on the dropped channel. It would also allow the request address to be Not entirely sure what's best honestly. Curious what you think about it @lulf . |
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 agree readability suffers a bit now, and also I find macros reduce readability even more. I don't have any good ideas, but maybe panicking for the edge cases is better to simplify
Yea that's what I also feel like. I'll come up with another PR for panicking when a request is cancelled. |
Cancelled in favor of #14 |
Fixes #11
Note that the previous implementations was removed, we could keep them and add the cancel limitation in the comments.
It's starting to get a bit unwieldy for the typing when things need to specify the types and generics are not supported (ex: embassy tasks).
ActoRequest
now uses a mutable reference to avoid doing two request from the sameActorRequest
and joining them since the first reply could be associated with the second request for example.