Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
1d6e5dc4
Commit
1d6e5dc4
authored
Aug 18, 2019
by
Oran Agra
Browse files
Module INFO, add support for dict fields, rename API to have common prefix
parent
e91d9a6f
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/module.c
View file @
1d6e5dc4
...
@@ -43,9 +43,10 @@
...
@@ -43,9 +43,10 @@
typedef struct RedisModuleInfoCtx {
typedef struct RedisModuleInfoCtx {
struct RedisModule *module;
struct RedisModule *module;
sds requested_section;
sds requested_section;
sds info; /* info string we collected so far */
sds info; /* info string we collected so far */
int sections; /* number of sections we collected so far */
int sections; /* number of sections we collected so far */
int in_section; /* indication if we're in an active section or not */
int in_section; /* indication if we're in an active section or not */
int in_dict_field; /* indication that we're curreintly appending to a dict */
} RedisModuleInfoCtx;
} RedisModuleInfoCtx;
typedef void (*RedisModuleInfoFunc)(RedisModuleInfoCtx *ctx, int for_crash_report);
typedef void (*RedisModuleInfoFunc)(RedisModuleInfoCtx *ctx, int for_crash_report);
...
@@ -4704,12 +4705,18 @@ int RM_DictCompare(RedisModuleDictIter *di, const char *op, RedisModuleString *k
...
@@ -4704,12 +4705,18 @@ int RM_DictCompare(RedisModuleDictIter *di, const char *op, RedisModuleString *k
* Modules Info fields
* Modules Info fields
* -------------------------------------------------------------------------- */
* -------------------------------------------------------------------------- */
int RM_InfoEndDictField(RedisModuleInfoCtx *ctx);
/* Used to start a new section, before adding any fields. the section name will
/* Used to start a new section, before adding any fields. the section name will
* be prefixed by "<modulename>_" and must only include A-Z,a-z,0-9.
* be prefixed by "<modulename>_" and must only include A-Z,a-z,0-9.
* When return value is REDISMODULE_ERR, the section should and will be skipped. */
* When return value is REDISMODULE_ERR, the section should and will be skipped. */
int RM_
Add
InfoSection(RedisModuleInfoCtx *ctx, char *name) {
int RM_Info
Add
Section(RedisModuleInfoCtx *ctx, char *name) {
sds full_name = sdscatprintf(sdsdup(ctx->module->name), "_%s", name);
sds full_name = sdscatprintf(sdsdup(ctx->module->name), "_%s", name);
/* Implicitly end dicts, instead of returning an error which is likely un checked. */
if (ctx->in_dict_field)
RM_InfoEndDictField(ctx);
/* proceed only if:
/* proceed only if:
* 1) no section was requested (emit all)
* 1) no section was requested (emit all)
* 2) the module name was requested (emit all)
* 2) the module name was requested (emit all)
...
@@ -4729,12 +4736,48 @@ int RM_AddInfoSection(RedisModuleInfoCtx *ctx, char *name) {
...
@@ -4729,12 +4736,48 @@ int RM_AddInfoSection(RedisModuleInfoCtx *ctx, char *name) {
return REDISMODULE_OK;
return REDISMODULE_OK;
}
}
/* Starts a dict field, similar to the ones in INFO KEYSPACE. Use normal
* RedisModule_InfoAddField* functions to add the items to this field, and
* terminate with RedisModule_InfoEndDictField. */
int RM_InfoBeginDictField(RedisModuleInfoCtx *ctx, char *name) {
if (!ctx->in_section)
return REDISMODULE_ERR;
/* Implicitly end dicts, instead of returning an error which is likely un checked. */
if (ctx->in_dict_field)
RM_InfoEndDictField(ctx);
ctx->info = sdscatprintf(ctx->info,
"%s_%s:",
ctx->module->name,
name);
ctx->in_dict_field = 1;
return REDISMODULE_OK;
}
/* Ends a dict field, see RedisModule_InfoBeginDictField */
int RM_InfoEndDictField(RedisModuleInfoCtx *ctx) {
if (!ctx->in_dict_field)
return REDISMODULE_ERR;
/* trim the last ',' if found. */
if (ctx->info[sdslen(ctx->info)-1]==',')
sdsIncrLen(ctx->info, -1);
ctx->info = sdscatprintf(ctx->info, "\r\n");
ctx->in_dict_field = 0;
return REDISMODULE_OK;
}
/* Used by RedisModuleInfoFunc to add info fields.
/* Used by RedisModuleInfoFunc to add info fields.
* Each field will be automatically prefixed by "<modulename>_".
* Each field will be automatically prefixed by "<modulename>_".
* Field names or values must not include \r\n of ":" */
* Field names or values must not include \r\n of ":" */
int RM_
Add
InfoFieldString(RedisModuleInfoCtx *ctx, char *field, RedisModuleString *value) {
int RM_Info
Add
FieldString(RedisModuleInfoCtx *ctx, char *field, RedisModuleString *value) {
if (!ctx->in_section)
if (!ctx->in_section)
return REDISMODULE_ERR;
return REDISMODULE_ERR;
if (ctx->in_dict_field) {
ctx->info = sdscatprintf(ctx->info,
"%s=%s,",
field,
(sds)value->ptr);
return REDISMODULE_OK;
}
ctx->info = sdscatprintf(ctx->info,
ctx->info = sdscatprintf(ctx->info,
"%s_%s:%s\r\n",
"%s_%s:%s\r\n",
ctx->module->name,
ctx->module->name,
...
@@ -4743,9 +4786,16 @@ int RM_AddInfoFieldString(RedisModuleInfoCtx *ctx, char *field, RedisModuleStrin
...
@@ -4743,9 +4786,16 @@ int RM_AddInfoFieldString(RedisModuleInfoCtx *ctx, char *field, RedisModuleStrin
return REDISMODULE_OK;
return REDISMODULE_OK;
}
}
int RM_
Add
InfoFieldCString(RedisModuleInfoCtx *ctx, char *field, char *value) {
int RM_Info
Add
FieldCString(RedisModuleInfoCtx *ctx, char *field, char *value) {
if (!ctx->in_section)
if (!ctx->in_section)
return REDISMODULE_ERR;
return REDISMODULE_ERR;
if (ctx->in_dict_field) {
ctx->info = sdscatprintf(ctx->info,
"%s=%s,",
field,
value);
return REDISMODULE_OK;
}
ctx->info = sdscatprintf(ctx->info,
ctx->info = sdscatprintf(ctx->info,
"%s_%s:%s\r\n",
"%s_%s:%s\r\n",
ctx->module->name,
ctx->module->name,
...
@@ -4754,9 +4804,16 @@ int RM_AddInfoFieldCString(RedisModuleInfoCtx *ctx, char *field, char *value) {
...
@@ -4754,9 +4804,16 @@ int RM_AddInfoFieldCString(RedisModuleInfoCtx *ctx, char *field, char *value) {
return REDISMODULE_OK;
return REDISMODULE_OK;
}
}
int RM_
Add
InfoFieldDouble(RedisModuleInfoCtx *ctx, char *field, double value) {
int RM_Info
Add
FieldDouble(RedisModuleInfoCtx *ctx, char *field, double value) {
if (!ctx->in_section)
if (!ctx->in_section)
return REDISMODULE_ERR;
return REDISMODULE_ERR;
if (ctx->in_dict_field) {
ctx->info = sdscatprintf(ctx->info,
"%s=%.17g,",
field,
value);
return REDISMODULE_OK;
}
ctx->info = sdscatprintf(ctx->info,
ctx->info = sdscatprintf(ctx->info,
"%s_%s:%.17g\r\n",
"%s_%s:%.17g\r\n",
ctx->module->name,
ctx->module->name,
...
@@ -4765,9 +4822,16 @@ int RM_AddInfoFieldDouble(RedisModuleInfoCtx *ctx, char *field, double value) {
...
@@ -4765,9 +4822,16 @@ int RM_AddInfoFieldDouble(RedisModuleInfoCtx *ctx, char *field, double value) {
return REDISMODULE_OK;
return REDISMODULE_OK;
}
}
int RM_
Add
InfoFieldLongLong(RedisModuleInfoCtx *ctx, char *field, long long value) {
int RM_Info
Add
FieldLongLong(RedisModuleInfoCtx *ctx, char *field, long long value) {
if (!ctx->in_section)
if (!ctx->in_section)
return REDISMODULE_ERR;
return REDISMODULE_ERR;
if (ctx->in_dict_field) {
ctx->info = sdscatprintf(ctx->info,
"%s=%lld,",
field,
value);
return REDISMODULE_OK;
}
ctx->info = sdscatprintf(ctx->info,
ctx->info = sdscatprintf(ctx->info,
"%s_%s:%lld\r\n",
"%s_%s:%lld\r\n",
ctx->module->name,
ctx->module->name,
...
@@ -4776,9 +4840,16 @@ int RM_AddInfoFieldLongLong(RedisModuleInfoCtx *ctx, char *field, long long valu
...
@@ -4776,9 +4840,16 @@ int RM_AddInfoFieldLongLong(RedisModuleInfoCtx *ctx, char *field, long long valu
return REDISMODULE_OK;
return REDISMODULE_OK;
}
}
int RM_
Add
InfoFieldULongLong(RedisModuleInfoCtx *ctx, char *field, unsigned long long value) {
int RM_Info
Add
FieldULongLong(RedisModuleInfoCtx *ctx, char *field, unsigned long long value) {
if (!ctx->in_section)
if (!ctx->in_section)
return REDISMODULE_ERR;
return REDISMODULE_ERR;
if (ctx->in_dict_field) {
ctx->info = sdscatprintf(ctx->info,
"%s=%llu,",
field,
value);
return REDISMODULE_OK;
}
ctx->info = sdscatprintf(ctx->info,
ctx->info = sdscatprintf(ctx->info,
"%s_%s:%llu\r\n",
"%s_%s:%llu\r\n",
ctx->module->name,
ctx->module->name,
...
@@ -4802,6 +4873,9 @@ sds modulesCollectInfo(sds info, sds section, int for_crash_report, int sections
...
@@ -4802,6 +4873,9 @@ sds modulesCollectInfo(sds info, sds section, int for_crash_report, int sections
continue;
continue;
RedisModuleInfoCtx info_ctx = {module, section, info, sections, 0};
RedisModuleInfoCtx info_ctx = {module, section, info, sections, 0};
module->info_cb(&info_ctx, for_crash_report);
module->info_cb(&info_ctx, for_crash_report);
/* Implicitly end dicts (no way to handle errors, and we must add the newline). */
if (info_ctx.in_dict_field)
RM_InfoEndDictField(&info_ctx);
info = info_ctx.info;
info = info_ctx.info;
sections = info_ctx.sections;
sections = info_ctx.sections;
}
}
...
@@ -5614,10 +5688,12 @@ void moduleRegisterCoreAPI(void) {
...
@@ -5614,10 +5688,12 @@ void moduleRegisterCoreAPI(void) {
REGISTER_API(CommandFilterArgReplace);
REGISTER_API(CommandFilterArgReplace);
REGISTER_API(CommandFilterArgDelete);
REGISTER_API(CommandFilterArgDelete);
REGISTER_API(RegisterInfoFunc);
REGISTER_API(RegisterInfoFunc);
REGISTER_API(AddInfoSection);
REGISTER_API(InfoAddSection);
REGISTER_API(AddInfoFieldString);
REGISTER_API(InfoBeginDictField);
REGISTER_API(AddInfoFieldCString);
REGISTER_API(InfoEndDictField);
REGISTER_API(AddInfoFieldDouble);
REGISTER_API(InfoAddFieldString);
REGISTER_API(AddInfoFieldLongLong);
REGISTER_API(InfoAddFieldCString);
REGISTER_API(AddInfoFieldULongLong);
REGISTER_API(InfoAddFieldDouble);
REGISTER_API(InfoAddFieldLongLong);
REGISTER_API(InfoAddFieldULongLong);
}
}
src/redismodule.h
View file @
1d6e5dc4
...
@@ -320,12 +320,14 @@ RedisModuleString *REDISMODULE_API_FUNC(RedisModule_DictPrev)(RedisModuleCtx *ct
...
@@ -320,12 +320,14 @@ RedisModuleString *REDISMODULE_API_FUNC(RedisModule_DictPrev)(RedisModuleCtx *ct
int
REDISMODULE_API_FUNC
(
RedisModule_DictCompareC
)(
RedisModuleDictIter
*
di
,
const
char
*
op
,
void
*
key
,
size_t
keylen
);
int
REDISMODULE_API_FUNC
(
RedisModule_DictCompareC
)(
RedisModuleDictIter
*
di
,
const
char
*
op
,
void
*
key
,
size_t
keylen
);
int
REDISMODULE_API_FUNC
(
RedisModule_DictCompare
)(
RedisModuleDictIter
*
di
,
const
char
*
op
,
RedisModuleString
*
key
);
int
REDISMODULE_API_FUNC
(
RedisModule_DictCompare
)(
RedisModuleDictIter
*
di
,
const
char
*
op
,
RedisModuleString
*
key
);
int
REDISMODULE_API_FUNC
(
RedisModule_RegisterInfoFunc
)(
RedisModuleCtx
*
ctx
,
RedisModuleInfoFunc
cb
);
int
REDISMODULE_API_FUNC
(
RedisModule_RegisterInfoFunc
)(
RedisModuleCtx
*
ctx
,
RedisModuleInfoFunc
cb
);
int
REDISMODULE_API_FUNC
(
RedisModule_AddInfoSection
)(
RedisModuleInfoCtx
*
ctx
,
char
*
name
);
int
REDISMODULE_API_FUNC
(
RedisModule_InfoAddSection
)(
RedisModuleInfoCtx
*
ctx
,
char
*
name
);
int
REDISMODULE_API_FUNC
(
RedisModule_AddInfoFieldString
)(
RedisModuleInfoCtx
*
ctx
,
char
*
field
,
RedisModuleString
*
value
);
int
REDISMODULE_API_FUNC
(
RedisModule_InfoBeginDictField
)(
RedisModuleInfoCtx
*
ctx
,
char
*
name
);
int
REDISMODULE_API_FUNC
(
RedisModule_AddInfoFieldCString
)(
RedisModuleInfoCtx
*
ctx
,
char
*
field
,
char
*
value
);
int
REDISMODULE_API_FUNC
(
RedisModule_InfoEndDictField
)(
RedisModuleInfoCtx
*
ctx
);
int
REDISMODULE_API_FUNC
(
RedisModule_AddInfoFieldDouble
)(
RedisModuleInfoCtx
*
ctx
,
char
*
field
,
double
value
);
int
REDISMODULE_API_FUNC
(
RedisModule_InfoAddFieldString
)(
RedisModuleInfoCtx
*
ctx
,
char
*
field
,
RedisModuleString
*
value
);
int
REDISMODULE_API_FUNC
(
RedisModule_AddInfoFieldLongLong
)(
RedisModuleInfoCtx
*
ctx
,
char
*
field
,
long
long
value
);
int
REDISMODULE_API_FUNC
(
RedisModule_InfoAddFieldCString
)(
RedisModuleInfoCtx
*
ctx
,
char
*
field
,
char
*
value
);
int
REDISMODULE_API_FUNC
(
RedisModule_AddInfoFieldULongLong
)(
RedisModuleInfoCtx
*
ctx
,
char
*
field
,
unsigned
long
long
value
);
int
REDISMODULE_API_FUNC
(
RedisModule_InfoAddFieldDouble
)(
RedisModuleInfoCtx
*
ctx
,
char
*
field
,
double
value
);
int
REDISMODULE_API_FUNC
(
RedisModule_InfoAddFieldLongLong
)(
RedisModuleInfoCtx
*
ctx
,
char
*
field
,
long
long
value
);
int
REDISMODULE_API_FUNC
(
RedisModule_InfoAddFieldULongLong
)(
RedisModuleInfoCtx
*
ctx
,
char
*
field
,
unsigned
long
long
value
);
/* Experimental APIs */
/* Experimental APIs */
#ifdef REDISMODULE_EXPERIMENTAL_API
#ifdef REDISMODULE_EXPERIMENTAL_API
...
@@ -500,12 +502,14 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int
...
@@ -500,12 +502,14 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int
REDISMODULE_GET_API
(
DictCompare
);
REDISMODULE_GET_API
(
DictCompare
);
REDISMODULE_GET_API
(
DictCompareC
);
REDISMODULE_GET_API
(
DictCompareC
);
REDISMODULE_GET_API
(
RegisterInfoFunc
);
REDISMODULE_GET_API
(
RegisterInfoFunc
);
REDISMODULE_GET_API
(
AddInfoSection
);
REDISMODULE_GET_API
(
InfoAddSection
);
REDISMODULE_GET_API
(
AddInfoFieldString
);
REDISMODULE_GET_API
(
InfoBeginDictField
);
REDISMODULE_GET_API
(
AddInfoFieldCString
);
REDISMODULE_GET_API
(
InfoEndDictField
);
REDISMODULE_GET_API
(
AddInfoFieldDouble
);
REDISMODULE_GET_API
(
InfoAddFieldString
);
REDISMODULE_GET_API
(
AddInfoFieldLongLong
);
REDISMODULE_GET_API
(
InfoAddFieldCString
);
REDISMODULE_GET_API
(
AddInfoFieldULongLong
);
REDISMODULE_GET_API
(
InfoAddFieldDouble
);
REDISMODULE_GET_API
(
InfoAddFieldLongLong
);
REDISMODULE_GET_API
(
InfoAddFieldULongLong
);
#ifdef REDISMODULE_EXPERIMENTAL_API
#ifdef REDISMODULE_EXPERIMENTAL_API
REDISMODULE_GET_API
(
GetThreadSafeContext
);
REDISMODULE_GET_API
(
GetThreadSafeContext
);
...
...
tests/modules/infotest.c
View file @
1d6e5dc4
...
@@ -3,19 +3,25 @@
...
@@ -3,19 +3,25 @@
#include <string.h>
#include <string.h>
void
InfoFunc
(
RedisModuleInfoCtx
*
ctx
,
int
for_crash_report
)
{
void
InfoFunc
(
RedisModuleInfoCtx
*
ctx
,
int
for_crash_report
)
{
RedisModule_
Add
InfoSection
(
ctx
,
"Spanish"
);
RedisModule_Info
Add
Section
(
ctx
,
"Spanish"
);
RedisModule_
Add
InfoFieldCString
(
ctx
,
"uno"
,
"one"
);
RedisModule_Info
Add
FieldCString
(
ctx
,
"uno"
,
"one"
);
RedisModule_
Add
InfoFieldLongLong
(
ctx
,
"dos"
,
2
);
RedisModule_Info
Add
FieldLongLong
(
ctx
,
"dos"
,
2
);
RedisModule_AddInfoSection
(
ctx
,
"Italian"
);
RedisModule_InfoAddSection
(
ctx
,
"Italian"
);
RedisModule_AddInfoFieldLongLong
(
ctx
,
"due"
,
2
);
RedisModule_InfoAddFieldLongLong
(
ctx
,
"due"
,
2
);
RedisModule_AddInfoFieldDouble
(
ctx
,
"tre"
,
3
.
3
);
RedisModule_InfoAddFieldDouble
(
ctx
,
"tre"
,
3
.
3
);
RedisModule_InfoAddSection
(
ctx
,
"keyspace"
);
RedisModule_InfoBeginDictField
(
ctx
,
"db0"
);
RedisModule_InfoAddFieldLongLong
(
ctx
,
"keys"
,
3
);
RedisModule_InfoAddFieldLongLong
(
ctx
,
"expires"
,
1
);
RedisModule_InfoEndDictField
(
ctx
);
if
(
for_crash_report
)
{
if
(
for_crash_report
)
{
RedisModule_
Add
InfoSection
(
ctx
,
"Klingon"
);
RedisModule_Info
Add
Section
(
ctx
,
"Klingon"
);
RedisModule_
Add
InfoFieldCString
(
ctx
,
"one"
,
"wa’"
);
RedisModule_Info
Add
FieldCString
(
ctx
,
"one"
,
"wa’"
);
RedisModule_
Add
InfoFieldCString
(
ctx
,
"two"
,
"cha’"
);
RedisModule_Info
Add
FieldCString
(
ctx
,
"two"
,
"cha’"
);
RedisModule_
Add
InfoFieldCString
(
ctx
,
"three"
,
"wej"
);
RedisModule_Info
Add
FieldCString
(
ctx
,
"three"
,
"wej"
);
}
}
}
}
...
...
tests/unit/moduleapi/infotest.tcl
View file @
1d6e5dc4
...
@@ -48,6 +48,11 @@ start_server {tags {"modules"}} {
...
@@ -48,6 +48,11 @@ start_server {tags {"modules"}} {
field $info infotest_uno
field $info infotest_uno
}
{
one
}
}
{
one
}
# TODO: test crash report.
test
{
module info dict
}
{
set info
[
r info infotest_keyspace
]
set keyspace
[
field $info infotest_db0
]
set keys
[
scan
[
regexp -inline
{
keys
\=
([
\d
]
*
)}
$keyspace
]
keys=%d
]
}
{
3
}
# TODO: test crash report.
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment