lua-users home
lua-l archive

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


2011/3/24 Alexander Gladysh <agladysh@gmail.com>:
> Hi, all!
>
> I'm working on bindings for hiredis Redis client library.
>
> Here is the library: https://github.com/antirez/hiredis
>
> Here is my module: https://github.com/agladysh/lua-hiredis (WARNING:
> work in progress.)
>
> I have question about error handling. (Sorry, I have to give some
> context first.)
>
> 1. In Redis one can do a transaction — atomically execute multiple
> commands, using MULTI/EXEC commands.
>
> More info here: http://redis.io/topics/transactions
>
> 2. If a command inside a transaction fails — all other commands are
> still executed.
>
> 3. On transport protocol level, MULTI/EXEC transaction results are
> transmitted to client as a reply to EXEC command.
>
> 4. This reply is in "multibulk" format (REDIS_REPLY_ARRAY) — an array
> of arrays (nesting level is not limited).
>
> 5. Command execution errors are encoded as a distinct transport
> protocol type. In hiredis — REDIS_REPLY_ERR.
>
> More info on hiredis API here:
> https://github.com/antirez/hiredis/blob/master/README.md
>
> My question: How to expose command execution errors to Lua code?
>
> See my current prototype implementation here: http://bit.ly/fDE5mc
>
> Now, whenever I see REDIS_REPLY_ERR redisResponse, I abort everything
> and just return nil, error_message.
>
> For multibulk replies it is plain wrong — user does want to see
> results of execution of other commands in MULTI/EXEC.
>
> To give some concrete example:
>
> MULTI
> SET a 3
> LPOP a
> INCR a
> EXEC
>
> Returns:
>
> 1. OK
> 2. (error) ERR Operation against a key holding the wrong kind of value
> 3. (integer) 4
>
> How should this result be returned to Lua?
>
> {
>  "OK",
>  -- how to express error message here?
>  4
> }
>
> Any hints?

How do you call the functions ? Assuming you have Lua calls mapping
directly to redis wire requests, maybe you can return some opaque
mutable object, that will be updated by the exec call, like :

multi()
local res1 = set('a', 3)
local res2 = lpop('a')
local res3 = incr('a')
-- using resx before calling exec would throw an error
exec()

print(res1.status, res1.value)
print(res2.status, res2.value)
print(res3.status, res3.value)