@@ -201,6 +201,7 @@ typedef struct ValkeyModuleCtx ValkeyModuleCtx;
201201#define VALKEYMODULE_CTX_CHANNELS_POS_REQUEST (1 << 8)
202202#define VALKEYMODULE_CTX_COMMAND (1 << 9) /* Context created to serve a command from call() or AOF (which calls cmd->proc directly) */
203203#define VALKEYMODULE_CTX_KEYSPACE_NOTIFICATION (1 << 10) /* Context created a keyspace notification event */
204+ #define VALKEYMODULE_CTX_SCRIPT_EXECUTION (1 << 11) /* Context created to serve a scripting engine execution */
204205
205206/* This represents a key opened with VM_OpenKey(). */
206207struct ValkeyModuleKey {
@@ -997,7 +998,7 @@ void moduleCreateContext(ValkeyModuleCtx *out_ctx, ValkeyModule *module, int ctx
997998void moduleScriptingEngineInitContext(ValkeyModuleCtx *out_ctx,
998999 ValkeyModule *module,
9991000 client *client) {
1000- moduleCreateContext(out_ctx, module, VALKEYMODULE_CTX_NONE );
1001+ moduleCreateContext(out_ctx, module, VALKEYMODULE_CTX_SCRIPT_EXECUTION );
10011002 out_ctx->client = client;
10021003}
10031004
@@ -6420,6 +6421,12 @@ ValkeyModuleCallReply *VM_Call(ValkeyModuleCtx *ctx, const char *cmdname, const
64206421 error_as_call_replies = flags & VALKEYMODULE_ARGV_CALL_REPLIES_AS_ERRORS;
64216422 va_end(ap);
64226423
6424+ int is_running_script = ctx->flags & VALKEYMODULE_CTX_SCRIPT_EXECUTION;
6425+
6426+ /* If we're calling a command with a script execution context, then a script
6427+ * execution runtime must exist.. */
6428+ serverAssert(!is_running_script || scriptIsRunning());
6429+
64236430 c = moduleAllocTempClient();
64246431
64256432 if (!(flags & VALKEYMODULE_ARGV_ALLOW_BLOCK)) {
@@ -6483,18 +6490,18 @@ ValkeyModuleCallReply *VM_Call(ValkeyModuleCtx *ctx, const char *cmdname, const
64836490 cmd_flags = getCommandFlags(c);
64846491
64856492 if (flags & VALKEYMODULE_ARGV_SCRIPT_MODE) {
6486- if (scriptIsRunning() ) {
6493+ if (is_running_script ) {
64876494 c->flag.module = 0;
64886495 c->flag.script = 1;
64896496 }
64906497
64916498 /* In script mode, commands with CMD_NOSCRIPT flag are normally forbidden.
64926499 * However, we allow them if both conditions are met:
6493- * 1. We're running in the context of a scripting engine (scriptIsRunning())
6500+ * 1. We're running in the context of a scripting engine running a script
64946501 * 2. The configuration option server.script_disable_deny_script is enabled
64956502 * If either condition is false, we block the command. */
64966503 if ((cmd_flags & CMD_NOSCRIPT)) {
6497- if (!scriptIsRunning() || !server.script_disable_deny_script) {
6504+ if (!is_running_script || !server.script_disable_deny_script) {
64986505 errno = ESPIPE;
64996506 if (error_as_call_replies) {
65006507 reply_error_msg = sdscatfmt(sdsempty(), "command '%S' is not allowed on script mode", c->cmd->fullname);
@@ -6503,7 +6510,7 @@ ValkeyModuleCallReply *VM_Call(ValkeyModuleCtx *ctx, const char *cmdname, const
65036510 }
65046511 }
65056512
6506- if (scriptIsRunning() && scriptAllowsOOM()) {
6513+ if (is_running_script && scriptAllowsOOM()) {
65076514 flags &= ~VALKEYMODULE_ARGV_RESPECT_DENY_OOM;
65086515 }
65096516 }
@@ -6610,15 +6617,16 @@ ValkeyModuleCallReply *VM_Call(ValkeyModuleCtx *ctx, const char *cmdname, const
66106617 * Note: For scripts, we consider may-replicate commands as write commands.
66116618 * This also makes it possible to allow read-only scripts to be run during
66126619 * CLIENT PAUSE WRITE. */
6613- if (scriptIsRunning() && scriptIsReadOnly() && (cmd_flags & (CMD_WRITE | CMD_MAY_REPLICATE))) {
6620+ if (is_running_script && scriptIsReadOnly() && (cmd_flags & (CMD_WRITE | CMD_MAY_REPLICATE))) {
66146621 errno = ENOSPC;
66156622 reply_error_msg = sdsnew("Write commands are not allowed from read-only scripts");
66166623 goto cleanup;
66176624 }
66186625
66196626 /* If the script already made a modification to the dataset, we can't
66206627 * fail it on unpredictable error state. */
6621- if ((scriptIsRunning() && !scriptIsWriteDirty() && cmd_flags & CMD_WRITE) || (!scriptIsRunning() && cmd_flags & CMD_WRITE)) {
6628+ if ((is_running_script && !scriptIsWriteDirty() && cmd_flags & CMD_WRITE) ||
6629+ (!is_running_script && cmd_flags & CMD_WRITE)) {
66226630 /* on script mode, if a command is a write command,
66236631 * We will not run it if we encounter disk error
66246632 * or we do not have enough replicas */
@@ -6650,7 +6658,7 @@ ValkeyModuleCallReply *VM_Call(ValkeyModuleCtx *ctx, const char *cmdname, const
66506658 goto cleanup;
66516659 }
66526660
6653- if (scriptIsRunning() ) {
6661+ if (is_running_script ) {
66546662 scriptSetWriteDirtyFlag();
66556663 }
66566664 }
@@ -6659,7 +6667,7 @@ ValkeyModuleCallReply *VM_Call(ValkeyModuleCtx *ctx, const char *cmdname, const
66596667 !(cmd_flags & CMD_STALE)) {
66606668 errno = ESPIPE;
66616669 if (error_as_call_replies) {
6662- if (scriptIsRunning() ) {
6670+ if (is_running_script ) {
66636671 reply_error_msg = sdsnew("Can not execute the command on a stale replica");
66646672 } else {
66656673 reply_error_msg = sdsdup(shared.primarydownerr->ptr);
@@ -6668,7 +6676,7 @@ ValkeyModuleCallReply *VM_Call(ValkeyModuleCtx *ctx, const char *cmdname, const
66686676 goto cleanup;
66696677 }
66706678
6671- if (scriptIsRunning() && server.cluster_enabled && !mustObeyClient(ctx->client)) {
6679+ if (is_running_script && server.cluster_enabled && !mustObeyClient(ctx->client)) {
66726680 if (c->slot != -1 && !scriptAllowsCrossSlot()) {
66736681 if (scriptGetSlot() == -1) {
66746682 scriptSetSlot(c->slot);
@@ -6709,7 +6717,7 @@ ValkeyModuleCallReply *VM_Call(ValkeyModuleCtx *ctx, const char *cmdname, const
67096717
67106718 if (c->flag.blocked) {
67116719 /* Blocking commands are not allowed when calling commands in scripting engines. */
6712- serverAssert(!scriptIsRunning() );
6720+ serverAssert(!is_running_script );
67136721 serverAssert(flags & VALKEYMODULE_ARGV_ALLOW_BLOCK);
67146722 serverAssert(ctx->module);
67156723 ValkeyModuleAsyncRMCallPromise *promise = zmalloc(sizeof(ValkeyModuleAsyncRMCallPromise));
0 commit comments