lua-scripting.rst 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. .. vim: set ts=3 sw=3 et :
  2. .. php:namespace:: Predis
  3. Lua scripting
  4. -------------
  5. Starting from Redis version 2.6.0, `EVAL`_ and `EVALSHA`_ can be used to
  6. evaluate scripts using the Lua interpreter built into Redis.
  7. Predis provides an abstraction for handling Lua scripts as if them were plain
  8. Redis commands.
  9. Additionally to the ``Command\ServerEval`` provided by Predis, the
  10. ``Command\ScriptedCommand`` base class can be used to build a higher abstraction
  11. for our "scripted" commands so that they will appear just like any other command
  12. on the client-side.
  13. Implementing Scripted Commands
  14. ==============================
  15. To implement a new scripted command on top of Predis you can start off by
  16. creating a new class that extends the ``Command\ScriptedCommand`` abstract base
  17. class.
  18. This class contains an abstract function ``getScript()`` you must implement in
  19. your command class. Here is where you actually return the Lua script as a
  20. string.
  21. In your class you can also implement the ``getKeysCount()`` function that
  22. specifies the number of arguments that should be considered as keys. The default
  23. behaviour for the base class is to return FALSE to indicate that all the
  24. elements of the arguments array should be considered as keys, but subclasses can
  25. enforce a static number of keys.
  26. Example::
  27. class IncrementExistingKeysBy extends ScriptedCommand
  28. {
  29. public function getKeysCount()
  30. {
  31. // Tell Predis to use all the arguments but the last one as arguments
  32. // for KEYS. The last one will be used to populate ARGV.
  33. return -1;
  34. }
  35. public function getScript()
  36. {
  37. return
  38. <<<LUA
  39. local cmd, insert = redis.call, table.insert
  40. local increment, results = ARGV[1], { }
  41. for idx, key in ipairs(KEYS) do
  42. if cmd('exists', key) == 1 then
  43. insert(results, idx, cmd('incrby', key, increment))
  44. else
  45. insert(results, idx, false)
  46. end
  47. end
  48. return results
  49. LUA;
  50. }
  51. }
  52. Registering Scripted Commands
  53. =============================
  54. A scripted command should then be registered in the server profile being used by
  55. the client instance and used just like any other client command::
  56. $client = new Predis\Client();
  57. $client->getProfile()->defineCommand('increxby', 'IncrementExistingKeysBy');
  58. $client->mset('foo', 10, 'foobar', 100);
  59. $client->increxby('foo', 'foofoo', 'foobar', 50);
  60. .. note::
  61. Internally, scripted commands use `EVALSHA`_ to refer to the Lua script by
  62. its SHA1 hash in order to save bandwidth, but they are capable of falling
  63. back to `EVAL`_ when needed.
  64. .. _Lua scripting: http://redis.io/commands/eval
  65. .. _EVALSHA: http://redis.io/commands/evalsha
  66. .. _EVAL: http://redis.io/commands/eval