Skip to content
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

Merged
merged 8 commits into from
Apr 17, 2024
Merged

Add suspend, resume and reconnect methods #64

merged 8 commits into from
Apr 17, 2024

Conversation

piotrpio
Copy link
Contributor

Signed-off-by: Piotr Piotrowski piotr@synadia.com

Signed-off-by: Piotr Piotrowski <piotr@synadia.com>
Copy link
Contributor

@mtmk mtmk left a 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.

if self.state == .connected {
self.state = .suspended
try await disconnect()
self.fire(.disconnected)
Copy link
Contributor

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?

Copy link
Member

@Jarema Jarema Apr 15, 2024

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.

Copy link
Contributor

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

Copy link
Contributor Author

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.

}

func resume() async throws {
guard self.state == .suspended else {
Copy link
Contributor

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, changed 👍

Copy link
Contributor

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.

Copy link
Contributor Author

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?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, using eventloop.execute { }

Copy link
Contributor Author

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>
Copy link
Contributor

@mtmk mtmk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

couple more suggestions

Task {
self.state = .closed
do {
try await self.disconnect()
Copy link
Contributor

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.

Copy link
Contributor Author

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.

self.state = .closed
try await disconnect()

let eventLoop = self.channel?.eventLoop ?? MultiThreadedEventLoopGroup.currentEventLoop!
Copy link
Contributor

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?

@piotrpio piotrpio requested a review from mtmk April 17, 2024 12:52
Copy link
Contributor

@mtmk mtmk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@piotrpio piotrpio merged commit 86326af into main Apr 17, 2024
3 checks passed
@piotrpio piotrpio deleted the ios-events branch April 17, 2024 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants