Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

scripting with mruby #848

Closed
wants to merge 34 commits into from

3 participants

@tricknotes

We have created a command REVAL to use mruby for scripting of Redis.

mruby is the lightweight implementation of the Ruby language complying to (part of) the ISO standard.
Ruby is good at processing strings, arrays, hashes, etc. with its pretty designed libraries.
With mruby, we can do complex data operations in Redis with simple scripts.

How do you think about this idea?
As this patch is still rough cutting, some works will be needed to fit with Redis.
(For example REVALSHA is not implemented. Not implemented features are listed later.)

If your feel positive about implementing scripting languages in Redis other than Lua, we would like to consider supporting JavaScript with v8.
JavaScript runs on both client-side and server-side.
If Redis supports JavaScript, we can write everything in JavaScript.

The usage of REVAL is as follows:


REVAL script numkeys key [key ...] arg [arg …]

Features

Run mruby in the context of Redis server.

> reval "[KEYS[0],KEYS[1],ARGV[0],ARGV[1]]" 2 key1 key2 first second
1) "key1"
2) "key2"
3) "first"
4) "second"

Call Redis commands from a mruby script. (same as EVAL command)

> reval "REDIS.call('set','foo','bar')" 0
OK

Conversion between mruby and Redis data types

Redis to mruby conversion table.

  • Redis integer reply -> mruby Integer
  • Redis bulk reply -> mruby String
  • Redis multi bulk reply -> mruby Array
  • Redis error reply -> mruby Exception
  • Redis Nil bulk reply and Nil multi bulk reply -> mruby nil

mruby to Redis conversion table.

  • mruby Integer -> Redis integer reply (the number is converted into an integer)
  • mruby String -> Redis bulk reply
  • mruby Array -> Redis multi bulk reply (truncated to the first nil inside the mruby array if any)
  • mruby Hash with a single ok key -> Redis status reply
  • mruby Hash with a single err key -> Redis error reply
  • mruby Error -> Redis error reply
  • mruby boolean false -> Redis Nil bulk reply
  • mruby boolean true -> Redis integer reply with value of 1.

(examples)

> reval "10" 0
(integer) 10

> reval "[1, 2, [3, 'Hello World!']]" 0
1) (integer) 1
2) (integer) 2
3) 1) (integer) 3
   2) "Hello World!"

> reval "REDIS.call('get', 'foo')" 0
"bar"

Not implemented yet

  • REVALSHA
  • REDIS.log
  • script timeout
tricknotes added some commits
@tricknotes tricknotes Add reval command interface 2bccf4f
@tricknotes tricknotes Compile with mruby d213cbe
@tricknotes tricknotes Disable stdio for mruby 7cbd470
@tricknotes tricknotes Evaluate first argument with mruby a6a5b4a
@tricknotes tricknotes Support type cast
- String
- Integer
- Array
440143f
@tricknotes tricknotes Handle mruby error a7dcd73
@tricknotes tricknotes Handle mruby nil 9d0a842
@tricknotes tricknotes Handle mruby hash 05470c5
@tricknotes tricknotes Define ARGV bd3b750
@tricknotes tricknotes Define KEYS c0f52a3
@tricknotes tricknotes Set constants of ARGV 2b1c6f7
@tricknotes tricknotes Add check for argc c14acfc
@tricknotes tricknotes Handle syntax error
For more details,
see `showcallinfo(mrb_state *mrb)` at `deps/mruby/tools/mruby/mruby.c`.
aef385b
@tricknotes tricknotes Add mruby object `REDIS` for redis interface ca474a4
@tricknotes tricknotes Parse redis object to mruby object cd4c990
@tricknotes tricknotes Return error when `REDIS.call` called with no argument d1d1f0e
@tricknotes tricknotes Update src/Makefile.dep
exec: `make dep`
e0188b7
@tricknotes tricknotes Check argument for redis command
- Wrong number of args
- Unknown command
f631e61
@tricknotes tricknotes Extract error handling 795a9ec
@tricknotes tricknotes Apply `zfree` 4ec09b8
@tricknotes tricknotes Deny command that is not allowed from scripts a53642b
@tricknotes tricknotes Check argument type 32b9a53
@tricknotes tricknotes Return error if mruby object is recursive 4463464
@tricknotes tricknotes Support mruby boolean as a redis type
- mruby true  -> redis (integer) 1
- mruby false -> redis (nil)

This spec is followed by `eval` command.
7536ad6
@tricknotes tricknotes Add tests about mruby 2d371d4
@tricknotes tricknotes Add test about type conversion (redis -> mruby) 386fa8e
@tricknotes tricknotes Skip cleanup when argument isn't given 445d05a
@tricknotes tricknotes Add test about `REDIS.call` in mruby e00cbdc
@tricknotes tricknotes Add test about mruby error f6afde1
@tricknotes tricknotes Support redis status in mruby 4a09195
@tricknotes tricknotes Add test about recursive mruby object 5a3aae7
@tricknotes tricknotes Support mruby float as a redis integer 9edc859
@tricknotes tricknotes Stop force string
unhandled value should be returned nil
5f6963c
@tricknotes tricknotes Add mruby script function `REDIS.pcall` a5851f6
@carlzulauf

This is an awesome idea :+1:

@antirez
Owner

Hello, thanks for your great effort, but as repeated may times in the past, the scripting will be limited to a single language: Lua. Redis lua scripts are not at the level of complexity where really a language should be different from the other, given that we are talking of similar late-binding very dynamic languages. So adding support for other languages would result in zero practical improvement and great complexity added. Thanks anyway!

@antirez antirez closed this
@JackieXie168 JackieXie168 referenced this pull request from a commit
@rntz rntz more explanation of issue #848 9795f3c
@JackieXie168 JackieXie168 referenced this pull request from a commit
@rntz rntz fix extproc interruptors, fixes #848 957fa56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Dec 23, 2012
  1. @tricknotes

    Add reval command interface

    tricknotes authored
  2. @tricknotes

    Compile with mruby

    tricknotes authored
  3. @tricknotes

    Disable stdio for mruby

    tricknotes authored
  4. @tricknotes
  5. @tricknotes

    Support type cast

    tricknotes authored
    - String
    - Integer
    - Array
  6. @tricknotes

    Handle mruby error

    tricknotes authored
  7. @tricknotes

    Handle mruby nil

    tricknotes authored
  8. @tricknotes

    Handle mruby hash

    tricknotes authored
  9. @tricknotes

    Define ARGV

    tricknotes authored
  10. @tricknotes

    Define KEYS

    tricknotes authored
  11. @tricknotes

    Set constants of ARGV

    tricknotes authored
  12. @tricknotes

    Add check for argc

    tricknotes authored
  13. @tricknotes

    Handle syntax error

    tricknotes authored
    For more details,
    see `showcallinfo(mrb_state *mrb)` at `deps/mruby/tools/mruby/mruby.c`.
  14. @tricknotes
  15. @tricknotes
  16. @tricknotes
  17. @tricknotes

    Update src/Makefile.dep

    tricknotes authored
    exec: `make dep`
  18. @tricknotes

    Check argument for redis command

    tricknotes authored
    - Wrong number of args
    - Unknown command
  19. @tricknotes

    Extract error handling

    tricknotes authored
  20. @tricknotes

    Apply `zfree`

    tricknotes authored
  21. @tricknotes
  22. @tricknotes

    Check argument type

    tricknotes authored
  23. @tricknotes
  24. @tricknotes

    Support mruby boolean as a redis type

    tricknotes authored
    - mruby true  -> redis (integer) 1
    - mruby false -> redis (nil)
    
    This spec is followed by `eval` command.
  25. @tricknotes

    Add tests about mruby

    tricknotes authored
  26. @tricknotes
  27. @tricknotes
  28. @tricknotes
  29. @tricknotes

    Add test about mruby error

    tricknotes authored
  30. @tricknotes
  31. @tricknotes
  32. @tricknotes
  33. @tricknotes

    Stop force string

    tricknotes authored
    unhandled value should be returned nil
  34. @tricknotes
Something went wrong with that request. Please try again.