

Redis Lua scripting implemented: how to play with it. - antirez
http://antirez.com/post/scripting-branch-released.html

======
mumrah
I think there needs to be some way to store scripts on the server. I like the
CouchDB method of a storing a view as a special document. Could use a Hash to
store the code along with metadata (version, last modified, etc).

That said, if Redis can EVAL a script stored as a String or a Hash->Key, the
client can deal with registering and versioning scripts.

Awesome work btw - been looking forward to scripting in Redis for a long time

~~~
almost
Have a look at the bottom of the article, antirez suggests that a EVALSHA
command might be implemented that would allow specification of a script by a
SHA1 hash.

Seems like a good idea to get the rest of it sorted before deciding on that
bit though.

------
pilif
Two things: 1) I think this is really cool, especially the guarantee that your
script is executed with the same atomicity as an internal command. That gives
you a lot of freedom to write simple stuff in a simple way without too much
worrying about concurrency (the INCREX sample on the linked page is a good
example of what I mean - the data doesn't change between the "exists" and the
"incr" call).

and 2) this opens a whole new playground for NoSQL injections: I don't know a
lot (well. anything) about lua embedding, but I could imagine that these lua
scripts somehow could get access to the file system. This means that you have
to be really, really careful not to expose redis to the outside world and not
to have it execute injected commands.

~~~
almost
The fact that it allows separate arguments should make injections
vulnerabilities a lot less likely to happen by accident since there shouldn't
be any need to interpolate you arguments into the code string (this would also
mess up the compiled function cache so you definitely want to do that anyway).

Also, LUA is a very small at core and I don't think it by default includes
things like file system access. You pretty much just get what the host
applications gives you, which in this case seems to be just the Redis API.

~~~
LeafStorm
First, it's Lua. Not LUA.

Secondly, it does include filesystem access by default, and right now there is
no decent protection against it. Hopefully, sandboxing will be implemented
before this reaches anything related to stable.

~~~
almost
You seem to be correct on both of those points.

Sandboxing Lua does seem quite easy though:
[http://stackoverflow.com/questions/1224708/how-can-i-
create-...](http://stackoverflow.com/questions/1224708/how-can-i-create-a-
secure-lua-sandbox)

------
wolfhumble
Would this work like a stored procedure in e.g. MySQL, though with the
disadvantage that it will not actually be stored within Redis and the
advantage that it uses a more powerful language, Lua?

~~~
Twisol
It looks that way. I've been playing with it and I've found two ways to
actually store and reuse scripts though:

1) Use loadstring() to compile and run a script from a Redis key. _EVAL
"return loadstring(redis('get', KEYS[1]))()" 1 foo_

2) Set a function as a global value, and call that. _EVAL "myfunc = function()
return 42" 0_ _EVAL "return myfunc()" 0_

antirez said in his previous post (<http://antirez.com/post/redis-and-
scripting.html>) that storing scripts has some problems with regard to Redis
Cluster, though.

------
sztanpet
the lua api of redis seems a bit un-lua like, redis.exists('key') would be
better also, returning a boolean for exists instead of a number, but it's such
a small nit-pick that it hardly wants mention

the possibilities this brings is quite huge tho, so quite excited

~~~
simonw
I quite like that the Lua API is a single function, because it means it
completely forward compatible already - the Lua API won't have to have new
methods added to it when Redis gets new commands.

~~~
antirez
Exactly, it also means: scripting engine _completely_ decoupled from all the
rest. Also it is much simpler to do things like dynamic execution of commands,
redis(my_command,"var")... or alike.

~~~
sztanpet
But it is just as easy to do that will a full userdata in lua. You just hook
up the newindex metamethod. Even more powerfull

