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

fix: ws server terminate subscriptions when connection is closed by the client. #483

Merged
merged 16 commits into from
Sep 24, 2021

Conversation

niklasad1
Copy link
Member

@niklasad1 niklasad1 commented Sep 22, 2021

Closing #481

The underlying issue is that receiver of the connection channel is not dropped when the connection is terminated and the correspond senders are stored in the subscription HashMap.

With this change the receiver is dropped when the connection is terminated and when SubscriptionSink::send is tried it will fail and cause the server the remove the subscription.

@@ -241,7 +241,13 @@ async fn background_task(
while !stop_monitor.shutdown_requested() {
data.clear();

method_executors.select_with(receiver.receive_data(&mut data)).await?;
if let Err(e) = method_executors.select_with(receiver.receive_data(&mut data)).await {
Copy link
Member Author

@niklasad1 niklasad1 Sep 22, 2021

Choose a reason for hiding this comment

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

NOTE; this will kill a connection on any soketto::connection::Error, not just if the client terminated the connection

In a follow-up PR I think we should try to do some graceful error handling

ws-server/src/server.rs Outdated Show resolved Hide resolved
@niklasad1 niklasad1 changed the title fix: server should not send to closed subscription fix: server should not send to closed subscriptions Sep 22, 2021
@niklasad1 niklasad1 changed the title fix: server should not send to closed subscriptions fix: server should not send data to closed subscriptions Sep 22, 2021
types/src/client.rs Outdated Show resolved Hide resolved
ws-client/src/helpers.rs Outdated Show resolved Hide resolved
ws-server/src/server.rs Outdated Show resolved Hide resolved
ws-server/src/server.rs Outdated Show resolved Hide resolved
ws-client/src/client.rs Outdated Show resolved Hide resolved
@niklasad1 niklasad1 changed the title fix: server should not send data to closed subscriptions fix: ws server terminate subscriptions when connection is closed by the client. Sep 24, 2021
ws-client/src/client.rs Outdated Show resolved Hide resolved
Comment on lines 336 to 337
// assert that the server received `SubscriptionClosed` after the client was dropped.
assert!(rx.next().await.is_some());
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a bit opaque unless one knows exactly what is going on.

Maybe we can do something like this?

	let sub_closed_err = rx.next().await.expect("Server received `SubscriptionClosed` after the client was dropped.");
	assert!(format!("{:?}", sub_closed_err).contains("is closed but not yet dropped"));

It's a bit annoying that SubscriptionClosedErr has a private member (and that there's no way for the client to know what the subscription ID is) or we could have used assert_matches here for better readability...

Copy link
Member Author

Choose a reason for hiding this comment

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

Yepp, I think we could replace SubscriptionClosed(String) with a better type.

Perhaps with a kind enum, to distinguish why the subscription was closed the error message is quite useful atm

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