Unverified Commit 45c99d70 authored by guybe7's avatar guybe7 Committed by GitHub
Browse files

Adds RM_Microseconds and RM_CachedMicroseconds (#11016)

RM_Microseconds
Return the wall-clock Unix time, in microseconds

RM_CachedMicroseconds
Returns a cached copy of the Unix time, in microseconds.
It is updated in the server cron job and before executing a command.
It is useful for complex call stacks, such as a command causing a
key space notification, causing a module to execute a RedisModule_Call,
causing another notification, etc.
It makes sense that all these callbacks would use the same clock.
parent 00097bf4
...@@ -2027,7 +2027,7 @@ int RM_IsModuleNameBusy(const char *name) { ...@@ -2027,7 +2027,7 @@ int RM_IsModuleNameBusy(const char *name) {
} }
/* Return the current UNIX time in milliseconds. */ /* Return the current UNIX time in milliseconds. */
long long RM_Milliseconds(void) { mstime_t RM_Milliseconds(void) {
return mstime(); return mstime();
} }
...@@ -2036,6 +2036,21 @@ uint64_t RM_MonotonicMicroseconds(void) { ...@@ -2036,6 +2036,21 @@ uint64_t RM_MonotonicMicroseconds(void) {
return getMonotonicUs(); return getMonotonicUs();
} }
/* Return the current UNIX time in microseconds */
ustime_t RM_Microseconds() {
return ustime();
}
/* Return the cached UNIX time in microseconds.
* It is updated in the server cron job and before executing a command.
* It is useful for complex call stacks, such as a command causing a
* key space notification, causing a module to execute a RedisModule_Call,
* causing another notification, etc.
* It makes sense that all this callbacks would use the same clock. */
ustime_t RM_CachedMicroseconds() {
return server.ustime;
}
/* Mark a point in time that will be used as the start time to calculate /* Mark a point in time that will be used as the start time to calculate
* the elapsed execution time when RM_BlockedClientMeasureTimeEnd() is called. * the elapsed execution time when RM_BlockedClientMeasureTimeEnd() is called.
* Within the same command, you can call multiple times * Within the same command, you can call multiple times
...@@ -12578,6 +12593,8 @@ void moduleRegisterCoreAPI(void) { ...@@ -12578,6 +12593,8 @@ void moduleRegisterCoreAPI(void) {
REGISTER_API(AbortBlock); REGISTER_API(AbortBlock);
REGISTER_API(Milliseconds); REGISTER_API(Milliseconds);
REGISTER_API(MonotonicMicroseconds); REGISTER_API(MonotonicMicroseconds);
REGISTER_API(Microseconds);
REGISTER_API(CachedMicroseconds);
REGISTER_API(BlockedClientMeasureTimeStart); REGISTER_API(BlockedClientMeasureTimeStart);
REGISTER_API(BlockedClientMeasureTimeEnd); REGISTER_API(BlockedClientMeasureTimeEnd);
REGISTER_API(GetThreadSafeContext); REGISTER_API(GetThreadSafeContext);
......
...@@ -752,6 +752,7 @@ typedef enum { ...@@ -752,6 +752,7 @@ typedef enum {
#ifndef REDISMODULE_CORE #ifndef REDISMODULE_CORE
typedef long long mstime_t; typedef long long mstime_t;
typedef long long ustime_t;
/* Macro definitions specific to individual compilers */ /* Macro definitions specific to individual compilers */
#ifndef REDISMODULE_ATTR_UNUSED #ifndef REDISMODULE_ATTR_UNUSED
...@@ -1055,8 +1056,10 @@ REDISMODULE_API int (*RedisModule_GetDbIdFromOptCtx)(RedisModuleKeyOptCtx *ctx) ...@@ -1055,8 +1056,10 @@ REDISMODULE_API int (*RedisModule_GetDbIdFromOptCtx)(RedisModuleKeyOptCtx *ctx)
REDISMODULE_API int (*RedisModule_GetToDbIdFromOptCtx)(RedisModuleKeyOptCtx *ctx) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_GetToDbIdFromOptCtx)(RedisModuleKeyOptCtx *ctx) REDISMODULE_ATTR;
REDISMODULE_API const RedisModuleString * (*RedisModule_GetKeyNameFromOptCtx)(RedisModuleKeyOptCtx *ctx) REDISMODULE_ATTR; REDISMODULE_API const RedisModuleString * (*RedisModule_GetKeyNameFromOptCtx)(RedisModuleKeyOptCtx *ctx) REDISMODULE_ATTR;
REDISMODULE_API const RedisModuleString * (*RedisModule_GetToKeyNameFromOptCtx)(RedisModuleKeyOptCtx *ctx) REDISMODULE_ATTR; REDISMODULE_API const RedisModuleString * (*RedisModule_GetToKeyNameFromOptCtx)(RedisModuleKeyOptCtx *ctx) REDISMODULE_ATTR;
REDISMODULE_API long long (*RedisModule_Milliseconds)(void) REDISMODULE_ATTR; REDISMODULE_API mstime_t (*RedisModule_Milliseconds)(void) REDISMODULE_ATTR;
REDISMODULE_API uint64_t (*RedisModule_MonotonicMicroseconds)(void) REDISMODULE_ATTR; REDISMODULE_API uint64_t (*RedisModule_MonotonicMicroseconds)(void) REDISMODULE_ATTR;
REDISMODULE_API ustime_t (*RedisModule_Microseconds)(void) REDISMODULE_ATTR;
REDISMODULE_API ustime_t (*RedisModule_CachedMicroseconds)(void) REDISMODULE_ATTR;
REDISMODULE_API void (*RedisModule_DigestAddStringBuffer)(RedisModuleDigest *md, const char *ele, size_t len) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_DigestAddStringBuffer)(RedisModuleDigest *md, const char *ele, size_t len) REDISMODULE_ATTR;
REDISMODULE_API void (*RedisModule_DigestAddLongLong)(RedisModuleDigest *md, long long ele) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_DigestAddLongLong)(RedisModuleDigest *md, long long ele) REDISMODULE_ATTR;
REDISMODULE_API void (*RedisModule_DigestEndSequence)(RedisModuleDigest *md) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_DigestEndSequence)(RedisModuleDigest *md) REDISMODULE_ATTR;
...@@ -1390,6 +1393,8 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int ...@@ -1390,6 +1393,8 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int
REDISMODULE_GET_API(GetToDbIdFromOptCtx); REDISMODULE_GET_API(GetToDbIdFromOptCtx);
REDISMODULE_GET_API(Milliseconds); REDISMODULE_GET_API(Milliseconds);
REDISMODULE_GET_API(MonotonicMicroseconds); REDISMODULE_GET_API(MonotonicMicroseconds);
REDISMODULE_GET_API(Microseconds);
REDISMODULE_GET_API(CachedMicroseconds);
REDISMODULE_GET_API(DigestAddStringBuffer); REDISMODULE_GET_API(DigestAddStringBuffer);
REDISMODULE_GET_API(DigestAddLongLong); REDISMODULE_GET_API(DigestAddLongLong);
REDISMODULE_GET_API(DigestEndSequence); REDISMODULE_GET_API(DigestEndSequence);
......
...@@ -30,10 +30,14 @@ ...@@ -30,10 +30,14 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#define _DEFAULT_SOURCE /* For usleep */
#include "redismodule.h" #include "redismodule.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <unistd.h>
ustime_t cached_time = 0;
/** stores all the keys on which we got 'loaded' keyspace notification **/ /** stores all the keys on which we got 'loaded' keyspace notification **/
RedisModuleDict *loaded_event_log = NULL; RedisModuleDict *loaded_event_log = NULL;
...@@ -59,6 +63,12 @@ static int KeySpace_NotificationLoaded(RedisModuleCtx *ctx, int type, const char ...@@ -59,6 +63,12 @@ static int KeySpace_NotificationLoaded(RedisModuleCtx *ctx, int type, const char
static int KeySpace_NotificationGeneric(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key) { static int KeySpace_NotificationGeneric(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key) {
REDISMODULE_NOT_USED(type); REDISMODULE_NOT_USED(type);
if (cached_time) {
RedisModule_Assert(cached_time == RedisModule_CachedMicroseconds());
usleep(1);
RedisModule_Assert(cached_time != RedisModule_Microseconds());
}
if (strcmp(event, "del") == 0) { if (strcmp(event, "del") == 0) {
RedisModuleString *copykey = RedisModule_CreateStringPrintf(ctx, "%s_copy", RedisModule_StringPtrLen(key, NULL)); RedisModuleString *copykey = RedisModule_CreateStringPrintf(ctx, "%s_copy", RedisModule_StringPtrLen(key, NULL));
RedisModuleCallReply* rep = RedisModule_Call(ctx, "DEL", "s!", copykey); RedisModuleCallReply* rep = RedisModule_Call(ctx, "DEL", "s!", copykey);
...@@ -158,6 +168,8 @@ static int cmdDelKeyCopy(RedisModuleCtx *ctx, RedisModuleString **argv, int argc ...@@ -158,6 +168,8 @@ static int cmdDelKeyCopy(RedisModuleCtx *ctx, RedisModuleString **argv, int argc
if (argc != 2) if (argc != 2)
return RedisModule_WrongArity(ctx); return RedisModule_WrongArity(ctx);
cached_time = RedisModule_CachedMicroseconds();
RedisModuleCallReply* rep = RedisModule_Call(ctx, "DEL", "s!", argv[1]); RedisModuleCallReply* rep = RedisModule_Call(ctx, "DEL", "s!", argv[1]);
if (!rep) { if (!rep) {
RedisModule_ReplyWithError(ctx, "NULL reply returned"); RedisModule_ReplyWithError(ctx, "NULL reply returned");
...@@ -165,6 +177,7 @@ static int cmdDelKeyCopy(RedisModuleCtx *ctx, RedisModuleString **argv, int argc ...@@ -165,6 +177,7 @@ static int cmdDelKeyCopy(RedisModuleCtx *ctx, RedisModuleString **argv, int argc
RedisModule_ReplyWithCallReply(ctx, rep); RedisModule_ReplyWithCallReply(ctx, rep);
RedisModule_FreeCallReply(rep); RedisModule_FreeCallReply(rep);
} }
cached_time = 0;
return REDISMODULE_OK; return REDISMODULE_OK;
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment