diff --git a/scripts/base/init-bare.zeek b/scripts/base/init-bare.zeek index a45c5904f1..98b16e103e 100644 --- a/scripts/base/init-bare.zeek +++ b/scripts/base/init-bare.zeek @@ -6233,7 +6233,7 @@ export { NOT_CONNECTED, ## Operation timed out. TIMEOUT, - ## Connection to backed was lost. + ## Connection to backed was lost unexpectedly. CONNECTION_LOST, ## Generic operation failed. OPERATION_FAILED, @@ -6241,7 +6241,8 @@ export { KEY_NOT_FOUND, ## Key requested for overwrite already exists. KEY_EXISTS, - ## Generic connection failure. + ## Generic connection-setup failure. This is not if the connection + ## was lost, but if it failed to be setup in the first place. CONNECTION_FAILED, ## Generic disconnection failure. DISCONNECTION_FAILED, diff --git a/src/storage/backend/redis/Redis.cc b/src/storage/backend/redis/Redis.cc index 869d89a22a..5d357239d2 100644 --- a/src/storage/backend/redis/Redis.cc +++ b/src/storage/backend/redis/Redis.cc @@ -173,6 +173,9 @@ OperationResult Redis::DoOpen(OpenResultCallback* cb, RecordValPtr options) { struct timeval timeout = {5, 0}; opt.connect_timeout = &timeout; + // The connection request below should be operation #1. + active_ops = 1; + async_ctx = redisAsyncConnectWithOptions(&opt); if ( async_ctx == nullptr || async_ctx->err ) { // This block doesn't necessarily mean the connection failed. It means @@ -189,8 +192,6 @@ OperationResult Redis::DoOpen(OpenResultCallback* cb, RecordValPtr options) { return {ReturnCode::CONNECTION_FAILED, errmsg}; } - ++active_ops; - // There's no way to pass privdata down to the connect handler like there is for // the other callbacks. Store the open callback so that it can be dealt with from // OnConnect(). @@ -236,19 +237,12 @@ OperationResult Redis::DoClose(OperationResultCallback* cb) { auto locked_scope = conditionally_lock(zeek::run_state::reading_traces, expire_mutex); connected = false; + close_cb = cb; redisAsyncDisconnect(async_ctx); ++active_ops; - if ( cb->IsSyncCallback() && ! zeek::run_state::terminating ) { - Poll(); - // TODO: handle response - } - - redisAsyncFree(async_ctx); - async_ctx = nullptr; - - return {ReturnCode::SUCCESS}; + return {ReturnCode::IN_PROGRESS}; } /** @@ -487,13 +481,21 @@ void Redis::OnConnect(int status) { void Redis::OnDisconnect(int status) { DBG_LOG(DBG_STORAGE, "Redis backend: disconnection event"); - --active_ops; connected = false; - - if ( status == REDIS_ERR ) + if ( status == REDIS_ERR ) { + // An error status indicates that the connection was lost unexpectedly and not + // via a request from backend. EnqueueBackendLost(async_ctx->errstr); - else + } + else { + --active_ops; + EnqueueBackendLost("Client disconnected"); + CompleteCallback(close_cb, {ReturnCode::SUCCESS}); + } + + redisAsyncFree(async_ctx); + async_ctx = nullptr; } void Redis::ProcessFd(int fd, int flags) { diff --git a/src/storage/backend/redis/Redis.h b/src/storage/backend/redis/Redis.h index c5ac1271de..2af6d9f501 100644 --- a/src/storage/backend/redis/Redis.h +++ b/src/storage/backend/redis/Redis.h @@ -69,6 +69,7 @@ private: std::deque reply_queue; OpenResultCallback* open_cb; + OperationResultCallback* close_cb; std::mutex expire_mutex; std::string server_addr;