diff --git a/include/ulib/net/client/redis.h b/include/ulib/net/client/redis.h index 89462c9b..a51343d1 100644 --- a/include/ulib/net/client/redis.h +++ b/include/ulib/net/client/redis.h @@ -59,15 +59,13 @@ * @brief UREDISClient is a wrapper to REDIS API */ -typedef void (*vPFcs)(const UString&); +typedef void (*vPFcs) (const UString&); +typedef void (*vPFcscs)(const UString&,const UString&); class U_EXPORT UREDISClient_Base : public UClient_Base, UEventFd { public: - ~UREDISClient_Base() - { - U_TRACE_DTOR(0, UREDISClient_Base) - } + ~UREDISClient_Base(); // RESPONSE @@ -735,14 +733,12 @@ public: return processRequest(U_RC_MULTIBULK, U_CONSTANT_TO_PARAM("UNSUBSCRIBE"), param, len); } + void unsubscribe(const UString& channel); // unregister the callback for messages published to the given channels + void subscribe(const UString& channel, vPFcscs callback); // register the callback for messages published to the given channels + // define method VIRTUAL of class UEventFd - virtual int handlerRead() U_DECL_FINAL - { - U_TRACE_NO_PARAM(0, "UREDISClient_Base::handlerRead()") - - U_RETURN(U_NOTIFIER_OK); - } + virtual int handlerRead() U_DECL_FINAL; virtual void handlerDelete() U_DECL_FINAL { @@ -774,6 +770,7 @@ protected: static ptrdiff_t diff; static UVector* pvec; static UREDISClient_Base* pthis; + static UHashMap* pchannelCallbackMap; UREDISClient_Base() : UClient_Base(U_NULLPTR) { diff --git a/src/ulib/net/client/redis.cpp b/src/ulib/net/client/redis.cpp index 1a9c3e72..2cae0a44 100644 --- a/src/ulib/net/client/redis.cpp +++ b/src/ulib/net/client/redis.cpp @@ -16,9 +16,20 @@ uint32_t UREDISClient_Base::start; ptrdiff_t UREDISClient_Base::diff; +UHashMap* UREDISClient_Base::pchannelCallbackMap; UVector* UREDISClient_Base::pvec; UREDISClient_Base* UREDISClient_Base::pthis; +UREDISClient_Base::~UREDISClient_Base() +{ + U_TRACE_DTOR(0, UREDISClient_Base) + + if (pchannelCallbackMap) + { + U_DELETE(pchannelCallbackMap) + } +} + // Connect to REDIS server void UREDISClient_Base::init() @@ -530,6 +541,68 @@ bool UREDISClient_Base::deleteKeys(const char* pattern, uint32_t len) // Delete U_RETURN(true); } +// PUB/SUB (@see http://redis.io/pubsub) + +void UREDISClient_Base::unsubscribe(const UString& channel) // unregister the callback for messages published to the given channels +{ + U_TRACE(0, "UREDISClient_Base::unsubscribe(%V)", channel.rep) + + if (pchannelCallbackMap == U_NULLPTR) + { + U_NEW(UHashMap, pchannelCallbackMap, UHashMap); + } + else + { + (void) pchannelCallbackMap->erase(channel); + } +} + +void UREDISClient_Base::subscribe(const UString& channel, vPFcscs callback) // register the callback for messages published to the given channels +{ + U_TRACE(0, "UREDISClient_Base::subscribe(%V,%p)", channel.rep, callback) + + if (pchannelCallbackMap == U_NULLPTR) + { + U_NEW(UHashMap, pchannelCallbackMap, UHashMap); + } + + pchannelCallbackMap->insert(channel, (const void*)callback); +} + +// define method VIRTUAL of class UEventFd + +int UREDISClient_Base::handlerRead() +{ + U_TRACE_NO_PARAM(0, "UREDISClient_Base::handlerRead()") + + U_INTERNAL_ASSERT_POINTER(pchannelCallbackMap) + + if ((clear(), UClient_Base::response.setEmpty(), UClient_Base::readResponse(U_SINGLE_READ))) + { + char prefix = UClient_Base::response[0]; + + if (prefix != U_RC_MULTIBULK) + { + err = (prefix == U_RC_ERROR ? U_RC_ERROR + : U_RC_ERR_PROTOCOL); + + U_RETURN(false); + } + + err = U_RC_OK; + + processResponse(); + + UString channel = vitem[1]; + + vPFcscs callback = (vPFcscs) pchannelCallbackMap->at(channel); + + if (callback) callback(channel, vitem[2]); + } + + U_RETURN(U_NOTIFIER_OK); +} + // DEBUG #if defined(U_STDCPP_ENABLE) && defined(DEBUG) diff --git a/tests/examples/TSA/tsaserial b/tests/examples/TSA/tsaserial index d09d57e1..cdaca0df 100644 --- a/tests/examples/TSA/tsaserial +++ b/tests/examples/TSA/tsaserial @@ -1 +1 @@ -040E +0415 diff --git a/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-json.dockerfile b/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-json.dockerfile index d5e01be2..21b34828 100644 --- a/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-json.dockerfile +++ b/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-json.dockerfile @@ -45,7 +45,7 @@ RUN tar xf ULib-${ULIB_VERSION}.tar.gz WORKDIR $IROOT/ULib-$ULIB_VERSION # AVOID "configure: error: newly created file is older than distributed files! Check your system clock" -#RUN cp /src/* src/ulib/net/server/plugin/usp +RUN cp /src/* src/ulib/net/server/plugin/usp RUN find . -exec touch {} \; RUN echo "userver {" >> $ULIB_ROOT/benchmark.cfg diff --git a/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-json_fit.dockerfile b/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-json_fit.dockerfile index 05ed313c..f934a6d9 100644 --- a/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-json_fit.dockerfile +++ b/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-json_fit.dockerfile @@ -45,7 +45,7 @@ RUN tar xf ULib-${ULIB_VERSION}.tar.gz WORKDIR $IROOT/ULib-$ULIB_VERSION # AVOID "configure: error: newly created file is older than distributed files! Check your system clock" -#RUN cp /src/* src/ulib/net/server/plugin/usp +RUN cp /src/* src/ulib/net/server/plugin/usp RUN find . -exec touch {} \; RUN echo "userver {" >> $ULIB_ROOT/benchmark.cfg diff --git a/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-mongodb.dockerfile b/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-mongodb.dockerfile index b4fa8aab..a45b93a1 100644 --- a/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-mongodb.dockerfile +++ b/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-mongodb.dockerfile @@ -51,7 +51,7 @@ RUN tar xf ULib-${ULIB_VERSION}.tar.gz WORKDIR $IROOT/ULib-$ULIB_VERSION # AVOID "configure: error: newly created file is older than distributed files! Check your system clock" -#RUN cp /src/* src/ulib/net/server/plugin/usp +RUN cp /src/* src/ulib/net/server/plugin/usp RUN find . -exec touch {} \; RUN echo "userver {" >> $ULIB_ROOT/benchmark.cfg diff --git a/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-mysql.dockerfile b/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-mysql.dockerfile index f5c6a8b1..73082cd0 100644 --- a/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-mysql.dockerfile +++ b/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-mysql.dockerfile @@ -45,7 +45,7 @@ RUN tar xf ULib-${ULIB_VERSION}.tar.gz WORKDIR $IROOT/ULib-$ULIB_VERSION # AVOID "configure: error: newly created file is older than distributed files! Check your system clock" -#RUN cp /src/* src/ulib/net/server/plugin/usp +RUN cp /src/* src/ulib/net/server/plugin/usp RUN find . -exec touch {} \; RUN echo "userver {" >> $ULIB_ROOT/benchmark.cfg diff --git a/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-plaintext_fit.dockerfile b/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-plaintext_fit.dockerfile index 9e77ae25..7801a2c2 100644 --- a/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-plaintext_fit.dockerfile +++ b/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-plaintext_fit.dockerfile @@ -45,7 +45,7 @@ RUN tar xf ULib-${ULIB_VERSION}.tar.gz WORKDIR $IROOT/ULib-$ULIB_VERSION # AVOID "configure: error: newly created file is older than distributed files! Check your system clock" -#RUN cp /src/* src/ulib/net/server/plugin/usp +RUN cp /src/* src/ulib/net/server/plugin/usp RUN find . -exec touch {} \; RUN echo "userver {" >> $ULIB_ROOT/benchmark.cfg diff --git a/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-postgres.dockerfile b/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-postgres.dockerfile index 53b8893d..f98e4b17 100644 --- a/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-postgres.dockerfile +++ b/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-postgres.dockerfile @@ -45,7 +45,7 @@ RUN tar xf ULib-${ULIB_VERSION}.tar.gz WORKDIR $IROOT/ULib-$ULIB_VERSION # AVOID "configure: error: newly created file is older than distributed files! Check your system clock" -#RUN cp /src/* src/ulib/net/server/plugin/usp +RUN cp /src/* src/ulib/net/server/plugin/usp RUN find . -exec touch {} \; RUN echo "userver {" >> $ULIB_ROOT/benchmark.cfg diff --git a/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-postgres_fit.dockerfile b/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-postgres_fit.dockerfile index 9adf337c..e1754828 100644 --- a/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-postgres_fit.dockerfile +++ b/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib-postgres_fit.dockerfile @@ -45,7 +45,7 @@ RUN tar xf ULib-${ULIB_VERSION}.tar.gz WORKDIR $IROOT/ULib-$ULIB_VERSION # AVOID "configure: error: newly created file is older than distributed files! Check your system clock" -#RUN cp /src/* src/ulib/net/server/plugin/usp +RUN cp /src/* src/ulib/net/server/plugin/usp RUN find . -exec touch {} \; RUN echo "userver {" >> $ULIB_ROOT/benchmark.cfg diff --git a/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib.dockerfile b/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib.dockerfile index eacaa486..5a2ce67e 100644 --- a/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib.dockerfile +++ b/tests/examples/benchmark/FrameworkBenchmarks/ULib/docker/ulib.dockerfile @@ -45,7 +45,7 @@ RUN tar xf ULib-${ULIB_VERSION}.tar.gz WORKDIR $IROOT/ULib-$ULIB_VERSION # AVOID "configure: error: newly created file is older than distributed files! Check your system clock" -#RUN cp /src/* src/ulib/net/server/plugin/usp +RUN cp /src/* src/ulib/net/server/plugin/usp RUN find . -exec touch {} \; RUN echo "userver {" >> $ULIB_ROOT/benchmark.cfg