| 1750 | } |
| 1751 | |
| 1752 | void scriptCommand(client *c) { |
| 1753 | if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"help")) { |
| 1754 | const char *help[] = { |
| 1755 | "DEBUG (YES|SYNC|NO)", |
| 1756 | " Set the debug mode for subsequent scripts executed.", |
| 1757 | "EXISTS <sha1> [<sha1> ...]", |
| 1758 | " Return information about the existence of the scripts in the script cache.", |
| 1759 | "FLUSH [ASYNC|SYNC]", |
| 1760 | " Flush the Lua scripts cache. Very dangerous on replicas.", |
| 1761 | " When called without the optional mode argument, the behavior is determined by the", |
| 1762 | " lazyfree-lazy-user-flush configuration directive. Valid modes are:", |
| 1763 | " * ASYNC: Asynchronously flush the scripts cache.", |
| 1764 | " * SYNC: Synchronously flush the scripts cache.", |
| 1765 | "KILL", |
| 1766 | " Kill the currently executing Lua script.", |
| 1767 | "LOAD <script>", |
| 1768 | " Load a script into the scripts cache without executing it.", |
| 1769 | NULL |
| 1770 | }; |
| 1771 | addReplyHelp(c, help); |
| 1772 | } else if (c->argc >= 2 && !strcasecmp(c->argv[1]->ptr,"flush")) { |
| 1773 | int async = 0; |
| 1774 | if (c->argc == 3 && !strcasecmp(c->argv[2]->ptr,"sync")) { |
| 1775 | async = 0; |
| 1776 | } else if (c->argc == 3 && !strcasecmp(c->argv[2]->ptr,"async")) { |
| 1777 | async = 1; |
| 1778 | } else if (c->argc == 2) { |
| 1779 | async = server.lazyfree_lazy_user_flush ? 1 : 0; |
| 1780 | } else { |
| 1781 | addReplyError(c,"SCRIPT FLUSH only support SYNC|ASYNC option"); |
| 1782 | return; |
| 1783 | } |
| 1784 | scriptingReset(async); |
| 1785 | addReply(c,shared.ok); |
| 1786 | replicationScriptCacheFlush(); |
| 1787 | server.dirty++; /* Propagating this command is a good idea. */ |
| 1788 | } else if (c->argc >= 2 && !strcasecmp(c->argv[1]->ptr,"exists")) { |
| 1789 | int j; |
| 1790 | |
| 1791 | addReplyArrayLen(c, c->argc-2); |
| 1792 | for (j = 2; j < c->argc; j++) { |
| 1793 | if (dictFind(server.lua_scripts,c->argv[j]->ptr)) |
| 1794 | addReply(c,shared.cone); |
| 1795 | else |
| 1796 | addReply(c,shared.czero); |
| 1797 | } |
| 1798 | } else if (c->argc == 3 && !strcasecmp(c->argv[1]->ptr,"load")) { |
| 1799 | sds sha = luaCreateFunction(c,server.lua,c->argv[2]); |
| 1800 | if (sha == NULL) return; /* The error was sent by luaCreateFunction(). */ |
| 1801 | addReplyBulkCBuffer(c,sha,40); |
| 1802 | forceCommandPropagation(c,PROPAGATE_REPL|PROPAGATE_AOF); |
| 1803 | } else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"kill")) { |
| 1804 | if (server.lua_caller == NULL) { |
| 1805 | addReplyError(c,"-NOTBUSY No scripts in execution right now."); |
| 1806 | } else if (server.lua_caller->flags & CLIENT_MASTER) { |
| 1807 | addReplyError(c,"-UNKILLABLE The busy script was sent by a master instance in the context of replication and cannot be killed."); |
| 1808 | } else if (server.lua_write_dirty) { |
| 1809 | addReplyError(c,"-UNKILLABLE Sorry the script already executed write commands against the dataset. You can either wait the script termination or kill the server in a hard way using the SHUTDOWN NOSAVE command."); |
nothing calls this directly
no test coverage detected