-
Notifications
You must be signed in to change notification settings - Fork 142
Description
I have a question about the policy of invoking callback handler.
When I call RedisAsyncClient::command()
during disconnected, callback function doesn't seems to be called. Is that intentional specification?
Here is the small example code that demonstrates the behavior.
I've tested it with f55ffdc.
#include <string>
#include <iostream>
#include <boost/asio/ip/address.hpp>
#include <redisclient/redisasyncclient.h>
int main() {
boost::asio::ip::address address = boost::asio::ip::address::from_string("127.0.0.1");
const unsigned short port = 6379;
boost::asio::ip::tcp::endpoint endpoint(address, port);
boost::asio::io_service ioService;
redisclient::RedisAsyncClient redis(ioService);
boost::system::error_code ec;
redis.connect(
endpoint,
[&]
(auto const& ec) {
if(ec) {
std::cerr << __LINE__ <<
": Can't connect to redis: " << ec.message() << std::endl;
return;
}
std::cout << __LINE__ <<
": Please restart redis service within 5 seconds for testing!" << std::endl;
sleep(5);
std::cout << __LINE__ <<
": do async command" << std::endl;
redis.command(
"SET",
{"key", "value"},
[&]
(auto const& result) {
if( result.isError() )
{
std::cerr << __LINE__ <<
": SET error: " << result.toString() << "\n";
return ;
}
std::cout << __LINE__ <<
": result: " << result.toString() << std::endl;
}
);
std::cout << __LINE__ <<
": finish async command" << std::endl;
}
);
std::function<void(boost::system::error_code const&)> handler;
handler =
[&handler, &redis, &endpoint]
(boost::system::error_code const& ec) {
if (ec) {
std::cout << __LINE__ <<
": ec: " << ec << std::endl;
redis.disconnect();
std::cout << __LINE__ <<
": trying reconnect inner..." << std::endl;
sleep(1);
redis.connect(
endpoint,
handler);
}
else {
std::cout << __LINE__ <<
": reconnect success" << std::endl;
}
};
redis.installErrorHandler(
[&](std::string const& ec) {
std::cout << __LINE__ <<
": ec: " << ec << std::endl;
std::cout << __LINE__ <<
": trying reconnect..." << std::endl;
redis.disconnect();
redis.connect(
endpoint,
handler
);
}
);
ioService.run();
}
When I run the program, the following message is appeared:
26: Please restart redis service within 5 seconds for testing!
Then if I do nothing within 5 seconds, I got the following message:
30: do async command
47: finish async command
43: result: OK
The last line (43) indicates that RedisAsyncClient::command()
callback is called.
If I restart redis service within 5 seconds, I got the following message:
26: Please restart redis service within 5 seconds for testing!
I do sudo systemctl restart redis.service
.
30: do async command
47: finish async command
76: ec: End of file
78: trying reconnect...
69: reconnect success
That indicates that RedisAsyncClient::command()
callback is NOT called. But the handler that is installed using Redis::installErrorHandler()
is called.
Is that expected behavior?
I want to implement automatic re-execute RedisAsyncClient::command()
mechanism if the redis connection is disconnected.
In order to do that, I think that the following mechanism is required:
- Prepare a queue.
- Before calling
RedisAsyncClient::command()
, I copy the contents of the command and push it to the queue. - If the
RedisAsyncClient::command()
callback is called, erase the pushed command. If installed error handler is called, reconnect to redis, and when reconnected, callRedisAsyncClient::command()
for each commands in the queue.
Before I implement it in my client program, I'd like to clarify the library spec.