-
Notifications
You must be signed in to change notification settings - Fork 169
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
Implement the "drain" feature for subscriptions and connections #1332
base: main
Are you sure you want to change the base?
Conversation
fffcb1d
to
8ebaedb
Compare
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.
Thank you for this contribution!
This looks really good.
Some comments added.
async-nats/src/lib.rs
Outdated
@@ -773,6 +793,27 @@ impl ConnectionHandler { | |||
Command::Flush { observer } => { | |||
self.flush_observers.push(observer); | |||
} | |||
Command::Drain { sid } => { | |||
let mut drain_sub = |sid: &u64, sub: &mut Subscription| { |
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 would pass by value here:
let mut drain_sub = |sid: &u64, sub: &mut Subscription| { | |
let mut drain_sub = |sid: u64, sub: &mut Subscription| { |
async-nats/src/lib.rs
Outdated
let mut drain_sub = |sid: &u64, sub: &mut Subscription| { | ||
sub.is_draining = true; | ||
self.connection.enqueue_write_op(&ClientOp::Unsubscribe { | ||
sid: *sid, |
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.
which allows to remove the dereference here
sid: *sid, | |
sid: sid, |
async-nats/src/lib.rs
Outdated
|
||
if let Some(sid) = sid { | ||
if let Some(sub) = self.subscriptions.get_mut(&sid) { | ||
drain_sub(&sid, sub); |
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.
and referencing here
async-nats/src/lib.rs
Outdated
} else { | ||
// sid isn't set, so drain the whole client | ||
self.is_draining = true; | ||
for (sid, sub) in self.subscriptions.iter_mut() { |
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.
for (sid, sub) in self.subscriptions.iter_mut() { | |
for (&sid, sub) in self.subscriptions.iter_mut() { |
// The entire connection is draining. This means we flushed outgoing messages in the previous | ||
// call to this fn, we handled any remaining messages from the server in the loop above, and | ||
// all subs were drained, so drain is complete and we should exit instead of processing any | ||
// further messages |
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 wonder if we should add new Event
variants - like Draining
and Closed
.
async-nats/src/lib.rs
Outdated
@@ -1251,6 +1293,48 @@ impl Subscriber { | |||
.await?; | |||
Ok(()) | |||
} | |||
|
|||
/// Unsubscribes immediately but leaves the stream open to allow any in-flight messages on the |
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.
Maybe subscription
instead of stream
? Sounds more direct on what is affected.
async-nats/src/lib.rs
Outdated
/// delivered | ||
/// | ||
/// # Examples | ||
/// ``` |
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.
Please add no_run
to examples - the demo server is not reliable enough :).
(CI was red because there was a typo in example. Should be fine after a rebase) |
@jsudano ping, if you missed the review 🙂 |
Apologies for the delay, was away from the computer last week. Really appreciate the review, will get the comments addressed this week! |
8ebaedb
to
aa13c20
Compare
} | ||
} else { | ||
// sid isn't set, so drain the whole client | ||
self.connector.events_tx.try_send(Event::Draining).ok(); |
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.
Assumed it was fine to ignore any errors here as they'd be pretty unlikely (the only scenario I could think of would be if the drain command was sent mid-shutdown, in which case it's fine to just ignore the error).
ExitReason::Closed => break, | ||
ExitReason::Closed => { | ||
// | ||
self.connector.events_tx.try_send(Event::Closed).ok(); |
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.
Similar to the other comment, this is more-or-less the last thing we'd do during a drain-shutdown so it's probably fine to ignore errors.
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.
It is, however please either remove the //
or add a comment there that explains why its ok.
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.
LGTM!
Just one leftover from I guess intended comment left.
ExitReason::Closed => break, | ||
ExitReason::Closed => { | ||
// | ||
self.connector.events_tx.try_send(Event::Closed).ok(); |
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.
It is, however please either remove the //
or add a comment there that explains why its ok.
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.
Oh sorry, missed the cargo fmt and linter errors.
After fixing them, it's good to merge ;).
…orgot to set handler.is_draining
…d` by value in closure; update doc comments
1fb87ab
to
77a3381
Compare
Oops, hopefully that last commit got all of them (I ran the commands from the validation runs locally and they passed at least) |
@jsudano Thanks! The test is missing |
Based on the proposal in #1325, implementing the functionality described in this NATS doc.
I would love suggestions for further tests. I tried adding tests for more complex timing/corner cases but they all wound up looking like exactly like the tests I have here