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

Watch stops listening to changes after server restart #186

Open
Sirozha1337 opened this issue Jul 28, 2023 · 3 comments
Open

Watch stops listening to changes after server restart #186

Sirozha1337 opened this issue Jul 28, 2023 · 3 comments

Comments

@Sirozha1337
Copy link

Describe the bug

Restarting a server with running etcd breaks watch in services running on other servers.

To Reproduce

  1. Run Server 1 with etcd
  2. Run Server 2 with a service using this library. Example code from service:
_client = new EtcdClient(_options.ConnectionString, _options.Port);
try {
     _client.WatchRangeAsync(prefix, callback, EnsureAuthentication(), cancellationToken: cancellationToken)
}
catch (Exception ex){
    _logger.LogError(ex, "Error in Watch!");
}
  1. Stop Server 1
  2. Check that there's no exception in Server 2
  3. Start Server 1
  4. Make changes to keys in etcd
  5. Check that there're no exceptions in Server 2 and "callback" is not called

Expected behavior
WatchRange should throw an error, just like it does when etcd server is restarted.

Additional context
It seems the problem is the difference between service shutdown and server shutdown:

  • When you shutdown a service and try to connect to it with telnet, you get a connection refused.
  • When you do the same with a server, you get a timeout.
@shubhamranjan
Copy link
Owner

Can you confirm the version of the library being used ? We do have retry logic in place for connection failures (StatusCode.Unavailable)

@Sirozha1337
Copy link
Author

Can you confirm the version of the library being used ? We do have retry logic in place for connection failures (StatusCode.Unavailable)

The latest one - 6.2.0-beta

I've managed to fix this problem by providing SocketsHttpHandler configured with timeouts in configureChannelOptions:

new EtcdClient(_options.ConnectionString, _options.Port, configureChannelOptions:
				channelOptions =>
				{
					var handler = new SocketsHttpHandler();
					handler.KeepAlivePingDelay = TimeSpan.FromSeconds(30);
					handler.KeepAlivePingTimeout = TimeSpan.FromSeconds(30);
					handler.KeepAlivePingPolicy = TimeSpan.FromSeconds(30);
					
					channelOptions.HttpHandler = handler;
					channelOptions.ThrowOperationCanceledOnCancellation = true;
				})

Default handler doesn't ping the connection, so it doesn't know that etcd is down. With this configuration it will send ping packets every 30 seconds and if they timeout it will throw an exception.

@shubhamranjan
Copy link
Owner

Thank you. That is a good recommendation, will see if some ideal defaults fits in.

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

No branches or pull requests

2 participants