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

Slate state when HttpClient reconnects #43

Open
VagnerGon opened this issue Aug 1, 2022 · 2 comments
Open

Slate state when HttpClient reconnects #43

VagnerGon opened this issue Aug 1, 2022 · 2 comments

Comments

@VagnerGon
Copy link

When a connection is interrupted, the ping thread marks the RedisHost as unavailable. But, when the connection is restored, it does not update the Available property. It seems that the AsyncTcpClient recovers itself, marking the client as Connected, but the Available property is not updated.

Note that the TcpClient will have the IsConnected property as true, but the Available property will remain as false

public async Task<Result> Connect(RedisDB db, RedisClient client)
{
if (!client.TcpClient.IsConnected)
{
var connStatus = await client.TcpClient.Connect();
if (connStatus.Connected)
{
this.Available = true;
if (!string.IsNullOrEmpty(Password))
{
Commands.AUTH auth = new Commands.AUTH(Password);
RedisRequest request = new RedisRequest(null, client, auth, typeof(string));
var result = await request.Execute(db);
if (result.ResultType == ResultType.DataError ||
result.ResultType == ResultType.Error
|| result.ResultType == ResultType.NetError)
return result;
}
Commands.SELECT select = new Commands.SELECT(DB);
var req = new RedisRequest(null, client, select, typeof(string));
var t = req.Execute(db);
t.Wait();
return t.Result;
}
else
{
this.Available = false;
return new Result { ResultType = ResultType.NetError, Messge = client.TcpClient.LastError.Message };
}
}
return new Result { ResultType = ResultType.Simple, Messge = "Connected" };

Steps to reproduce:

  • Host a local redis server
  • Make a call (in my case, from an asp.net core controller), e.g. INFO. Everything works as expected.
  • Now, shutdown the Redis instance
  • Make the call again. It should throw an exception and the host marked as Available = false
  • Start the Redis server again.
  • Make the same call (aspnet server should not be rebooted).
  • Exception is thrown as redis server is not available

The AsyncTcpClient changes to a Connected state, but the Available property is still false.

Changing the property before returning solved the issue for me:

this.Available = true;
return new Result { ResultType = ResultType.Simple, Messge = "Connected" }; 
@VagnerGon
Copy link
Author

I think the cause is the parallel Ping from ReadHosts and WriteHosts.
Both will call Connect method, but one that fails may flag the mConnected field as false, while the second thread has set as true.

https://github.com/beetlex-io/BeetleX/blob/ce6f9d91394dbed5f28a66b9efbd9a87f9d32e23/src/BeetleX/Clients/Clients.cs#L1019-L1105

@beetlex-io
Copy link
Owner

thanks

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