From bc77f94e19a45374454754b3489c1d2b536bdb08 Mon Sep 17 00:00:00 2001 From: Tuan Tran Date: Wed, 9 Aug 2023 16:57:45 +0200 Subject: [PATCH] Support client side caching when using sync interface - Provide parameters for user to enable client side caching. User must implement the callback and handle the PUSH message sending from server by himself. --- src/sw/redis++/command.h | 8 ++++++++ src/sw/redis++/connection.cpp | 19 +++++++++++++++++++ src/sw/redis++/connection.h | 14 ++++++++++++++ src/sw/redis++/connection_pool.cpp | 6 ++++++ 4 files changed, 47 insertions(+) diff --git a/src/sw/redis++/command.h b/src/sw/redis++/command.h index bc9338e..bd9dd74 100644 --- a/src/sw/redis++/command.h +++ b/src/sw/redis++/command.h @@ -47,6 +47,14 @@ inline void hello(Connection &connection, long long version) { connection.send("HELLO %lld", version); } +inline void client_tracking(Connection &connection, bool on) { + if (on) { + connection.send("CLIENT TRACKING ON"); + } else { + connection.send("CLIENT TRACKING OFF"); + } +} + inline void echo(Connection &connection, const StringView &msg) { connection.send("ECHO %b", msg.data(), msg.size()); } diff --git a/src/sw/redis++/connection.cpp b/src/sw/redis++/connection.cpp index 7b060e0..72249bf 100644 --- a/src/sw/redis++/connection.cpp +++ b/src/sw/redis++/connection.cpp @@ -275,6 +275,15 @@ void Connection::_set_options() { if (_opts.readonly) { _enable_readonly(); } + +#ifdef REDIS_PLUS_PLUS_RESP_VERSION_3 + if (_opts.resp > 2 && _opts.client_tracking && _opts.push_cb) { + _context()->privdata = _opts.privdata; + _context()->free_privdata = _opts.privdata_dtor; + set_push_callback(_opts.push_cb); + _set_client_tracking(true); + } +#endif } void Connection::_enable_readonly() { @@ -297,6 +306,16 @@ void Connection::_set_resp_version() { // TODO: parse hello reply. } +void Connection::_set_client_tracking(bool on) { + cmd::client_tracking(*this, on); + + auto reply = recv(); + + assert(reply); + + // TODO: parse reply. +} + void Connection::_auth() { const std::string DEFAULT_USER = "default"; diff --git a/src/sw/redis++/connection.h b/src/sw/redis++/connection.h index 8ca3684..a520fe7 100644 --- a/src/sw/redis++/connection.h +++ b/src/sw/redis++/connection.h @@ -87,6 +87,18 @@ struct ConnectionOptions { // RESP version. int resp = 2; +#ifdef REDIS_PLUS_PLUS_RESP_VERSION_3 + // https://redis.io/docs/manual/client-side-caching/ + bool client_tracking = false; + + // Optional user defined data/destructor + void *privdata = nullptr; + void (*privdata_dtor)(void *) = nullptr; + + // A user defined PUSH message callback + redisPushFn *push_cb = nullptr; +#endif + // For internal use, and might be removed in the future. DO NOT use it in client code. std::string _server_info() const; }; @@ -182,6 +194,8 @@ class Connection { void _set_resp_version(); + void _set_client_tracking(bool); + redisContext* _context(); ContextUPtr _ctx; diff --git a/src/sw/redis++/connection_pool.cpp b/src/sw/redis++/connection_pool.cpp index 41a8f74..7fce01b 100644 --- a/src/sw/redis++/connection_pool.cpp +++ b/src/sw/redis++/connection_pool.cpp @@ -30,6 +30,12 @@ ConnectionPool::ConnectionPool(const ConnectionPoolOptions &pool_opts, throw Error("CANNOT create an empty pool"); } +#ifdef REDIS_PLUS_PLUS_RESP_VERSION_3 + if (_opts.client_tracking && _pool_opts.size > 1) { + throw Error("CANNOT enable client tracking with pool size greater than 1"); + } +#endif + // Lazily create connections. }