-
Notifications
You must be signed in to change notification settings - Fork 4
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
Add suspend, resume and reconnect methods #64
Conversation
Signed-off-by: Piotr Piotrowski <piotr@synadia.com>
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.
Looks good, I only have a couple of questions.
Sources/Nats/NatsConnection.swift
Outdated
if self.state == .connected { | ||
self.state = .suspended | ||
try await disconnect() | ||
self.fire(.disconnected) |
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.
Should suspended and disconnect be different events? even though suspension technically closes the connection from the clients perspective we are keeping subscription state whereas disconnect should also clear that state?
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.
We were discussing those with @piotrpio
We should never clear the state of subscriptions and we should always recover them when reconnecting/resuming.
The only difference is that if you disconnect because of suspend, client will not try to reconnect automatically. In all other cases, it will.
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 guess my point is about the event types more than the state. For example when you call close()
we're emitting closed
as opposed to disconnected
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.
Yeah, I was wondering weather to add a new event type or not. I was not sure how useful it would be to add a new event type, separate from "disconnected". Now that I think about it, having separate event types would mean you would be able to easily catch and separate instances of disconnects not triggered by the client and potentially take some action. Meanwhile, suspending is always initiated by the library and thus may not need a callback (or have a different one). I'll add the new event type.
Sources/Nats/NatsConnection.swift
Outdated
} | ||
|
||
func resume() async throws { | ||
guard self.state == .suspended else { |
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.
should we make sure state changes are synchronized to avoid races?
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 point, changed 👍
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 checking the state than changing it could also be racy? if we ran them in the event loop we shouldn't need locks or we can lock read-modify if it won't cause deadlocks.
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.
So you mean managing the state as tasks in event loop right?
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.
yes, using eventloop.execute { }
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'm really not sure what would be the best approach here, but possibly it would be safer to execute these on event loop.
I took a stab at this, please take a look at the latest changes.
Signed-off-by: Piotr Piotrowski <piotr@synadia.com>
Signed-off-by: Piotr Piotrowski <piotr@synadia.com>
Signed-off-by: Piotr Piotrowski <piotr@synadia.com>
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.
couple more suggestions
Sources/Nats/NatsConnection.swift
Outdated
Task { | ||
self.state = .closed | ||
do { | ||
try await self.disconnect() |
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.
disconnect is essentially a call to channel.close()
and can be done without spawning a Task
.
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.
You're right. I wanted to re-use disconnect method but it does not make sense here.
Sources/Nats/NatsConnection.swift
Outdated
self.state = .closed | ||
try await disconnect() | ||
|
||
let eventLoop = self.channel?.eventLoop ?? MultiThreadedEventLoopGroup.currentEventLoop! |
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.
should we guard these instead? What are the cases channel being nil other than connect()
call not being done at this point?
Signed-off-by: Piotr Piotrowski <piotr@synadia.com>
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
Signed-off-by: Piotr Piotrowski piotr@synadia.com