lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


It was thus said that the Great Roman Gershman once stated:
> You may probably know that Redis has Lua engine inside, which exposes the
> `redis.call(...)` function.
> 
> Redis is famously single-threaded but if I would want to make it
> multi-threaded, Lua scripting is one of the bigger barriers to that.

  Single-threaded code is easier to reason about.  But one can make Lua
multi-threaded (as in, operating system level threads), but you will have to
implement the functions lua_lock() and lua_unlock() to generate a custom Lua
engine.

  Lua does support coroutines (think threads, but non-operating system
based, and entirely non-preemptive), so that is also an approach.  One I use
for instance, for my gopher server [1].

> Suppose I would need to protect each `redis.call` command with mutex - it
> would create potential contention and overhead around each `redis.call`
> within a script.
> 
> But for scripts that look like:
> ```
> redis.call('set', ...)
> redis.call('lpush', ....)
> ```
> I could theoretically recognize that these commands are not dependent on
> each other and pipeline them (batch them within a single protected atomic
> operation).

  It's harder than you think.  These:

	foo({ 1,2,3 },'hello')
	foo({ 4,5,6 },'goodbye')

are independent of each other.  But these:

	x = { 7 , 8 , 9 }
	foo(x,'welcome')
	foo(x,'come again')

might not be, if foo() changes the given table.  I don't know enough about
Redis to say if your example is truly independent or not, but tables are
passed by reference, not value.  The same holds true for userdata.  You have
to know the details about foo() to know if x is modified or not [2].

> From what I saw in practice, many Redis lua scripts used in Redis
> frameworks have blocks of commands that ignore return values, so they can
> be batched together.

  Maybe ... maybe not.

  -spc

[1]	https://github.com/spc476/port70
	which is based around this Lua code for managing coroutines:
	https://github.com/spc476/lua-conmanorg/blob/master/lua/nfl.lua

[2]	Even if foo() doesn't modify x, if it passes x on to some other
	function, that function could in turn modify x.  It's modifiable
	table references all the way down.