@@ -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 }
@@ -6611,15 +6618,16 @@ ValkeyModuleCallReply *VM_Call(ValkeyModuleCtx *ctx, const char *cmdname, const
66116618 * Note: For scripts, we consider may-replicate commands as write commands.
66126619 * This also makes it possible to allow read-only scripts to be run during
66136620 * CLIENT PAUSE WRITE. */
6614- if (scriptIsRunning() && scriptIsReadOnly() && (cmd_flags & (CMD_WRITE | CMD_MAY_REPLICATE))) {
6621+ if (is_running_script && scriptIsReadOnly() && (cmd_flags & (CMD_WRITE | CMD_MAY_REPLICATE))) {
66156622 errno = ENOSPC;
66166623 reply_error_msg = sdsnew("Write commands are not allowed from read-only scripts");
66176624 goto cleanup;
66186625 }
66196626
66206627 /* If the script already made a modification to the dataset, we can't
66216628 * fail it on unpredictable error state. */
6622- if ((scriptIsRunning() && !scriptIsWriteDirty() && cmd_flags & CMD_WRITE) || (!scriptIsRunning() && cmd_flags & CMD_WRITE)) {
6629+ if ((is_running_script && !scriptIsWriteDirty() && cmd_flags & CMD_WRITE) ||
6630+ (!is_running_script && cmd_flags & CMD_WRITE)) {
66236631 /* on script mode, if a command is a write command,
66246632 * We will not run it if we encounter disk error
66256633 * or we do not have enough replicas */
@@ -6651,7 +6659,7 @@ ValkeyModuleCallReply *VM_Call(ValkeyModuleCtx *ctx, const char *cmdname, const
66516659 goto cleanup;
66526660 }
66536661
6654- if (scriptIsRunning() ) {
6662+ if (is_running_script ) {
66556663 scriptSetWriteDirtyFlag();
66566664 }
66576665 }
@@ -6660,7 +6668,7 @@ ValkeyModuleCallReply *VM_Call(ValkeyModuleCtx *ctx, const char *cmdname, const
66606668 !(cmd_flags & CMD_STALE)) {
66616669 errno = ESPIPE;
66626670 if (error_as_call_replies) {
6663- if (scriptIsRunning() ) {
6671+ if (is_running_script ) {
66646672 reply_error_msg = sdsnew("Can not execute the command on a stale replica");
66656673 } else {
66666674 reply_error_msg = sdsdup(shared.primarydownerr->ptr);
@@ -6669,7 +6677,7 @@ ValkeyModuleCallReply *VM_Call(ValkeyModuleCtx *ctx, const char *cmdname, const
66696677 goto cleanup;
66706678 }
66716679
6672- if (scriptIsRunning() && server.cluster_enabled && !mustObeyClient(ctx->client)) {
6680+ if (is_running_script && server.cluster_enabled && !mustObeyClient(ctx->client)) {
66736681 if (c->slot != -1 && !scriptAllowsCrossSlot()) {
66746682 if (scriptGetSlot() == -1) {
66756683 scriptSetSlot(c->slot);
@@ -6710,7 +6718,7 @@ ValkeyModuleCallReply *VM_Call(ValkeyModuleCtx *ctx, const char *cmdname, const
67106718
67116719 if (c->flag.blocked) {
67126720 /* Blocking commands are not allowed when calling commands in scripting engines. */
6713- serverAssert(!scriptIsRunning() );
6721+ serverAssert(!is_running_script );
67146722 serverAssert(flags & VALKEYMODULE_ARGV_ALLOW_BLOCK);
67156723 serverAssert(ctx->module);
67166724 ValkeyModuleAsyncRMCallPromise *promise = zmalloc(sizeof(ValkeyModuleAsyncRMCallPromise));
0 commit comments