Helper function for when a command callback is called, in order to handle * details needed to correctly replicate commands. */
| 647 | /* Helper function for when a command callback is called, in order to handle |
| 648 | * details needed to correctly replicate commands. */ |
| 649 | void moduleHandlePropagationAfterCommandCallback(RedisModuleCtx *ctx) { |
| 650 | serverAssert(GlobalLocksAcquired()); |
| 651 | client *c = ctx->client; |
| 652 | |
| 653 | /* We don't need to do anything here if the context was never used |
| 654 | * in order to propagate commands. */ |
| 655 | if (!(ctx->flags & REDISMODULE_CTX_MULTI_EMITTED)) return; |
| 656 | |
| 657 | /* We don't need to do anything here if the server isn't inside |
| 658 | * a transaction. */ |
| 659 | if (!serverTL->propagate_in_transaction) return; |
| 660 | |
| 661 | /* If this command is executed from with Lua or MULTI/EXEC we do not |
| 662 | * need to propagate EXEC */ |
| 663 | if (serverTL->in_eval || serverTL->in_exec) return; |
| 664 | |
| 665 | /* Handle the replication of the final EXEC, since whatever a command |
| 666 | * emits is always wrapped around MULTI/EXEC. */ |
| 667 | alsoPropagate(cserver.execCommand,c->db->id,&shared.exec,1, |
| 668 | PROPAGATE_AOF|PROPAGATE_REPL); |
| 669 | afterPropagateExec(); |
| 670 | |
| 671 | /* If this is not a module command context (but is instead a simple |
| 672 | * callback context), we have to handle directly the "also propagate" |
| 673 | * array and emit it. In a module command call this will be handled |
| 674 | * directly by call(). */ |
| 675 | if (!(ctx->flags & REDISMODULE_CTX_MODULE_COMMAND_CALL) && |
| 676 | g_pserver->also_propagate.numops) |
| 677 | { |
| 678 | for (int j = 0; j < g_pserver->also_propagate.numops; j++) { |
| 679 | redisOp *rop = &g_pserver->also_propagate.ops[j]; |
| 680 | int target = rop->target; |
| 681 | if (target) |
| 682 | propagate(rop->cmd,rop->dbid,rop->argv,rop->argc,target); |
| 683 | } |
| 684 | redisOpArrayFree(&g_pserver->also_propagate); |
| 685 | /* Restore the previous oparray in case of nexted use of the API. */ |
| 686 | g_pserver->also_propagate = ctx->saved_oparray; |
| 687 | /* We're done with saved_oparray, let's invalidate it. */ |
| 688 | redisOpArrayInit(&ctx->saved_oparray); |
| 689 | } |
| 690 | } |
| 691 | |
| 692 | /* Free the context after the user function was called. */ |
| 693 | void moduleFreeContext(RedisModuleCtx *ctx, bool propogate) { |
no test coverage detected