Error handling strategy for Redis multi-bulk replies, in context of Lua bindings

classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

Error handling strategy for Redis multi-bulk replies, in context of Lua bindings

Alexander Gladysh
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?

Thanks,
Alexander.

P.S. Note that "OK" is a status reply (REDIS_REPLY_STATUS), not a
string (REDIS_REPLY_STRING). I'd like to separate those two as well,
but this is of much less priority (I think).

Reply | Threaded
Open this post in threaded view
|

Re: Error handling strategy for Redis multi-bulk replies, in context of Lua bindings

Robert G. Jakabosky
On Wednesday 23, Alexander Gladysh wrote:

> 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?
>
> Thanks,
> Alexander.
>
> P.S. Note that "OK" is a status reply (REDIS_REPLY_STATUS), not a
> string (REDIS_REPLY_STRING). I'd like to separate those two as well,
> but this is of much less priority (I think).

I would wrap status/error replies in a status userdata object with a is_error
field/method.  For string/number reply values convert them to basic lua
string/numbers.

--
Robert G. Jakabosky

Reply | Threaded
Open this post in threaded view
|

Re: Error handling strategy for Redis multi-bulk replies, in context of Lua bindings

Sean Conner
In reply to this post by Alexander Gladysh
It was thus said that the Great Alexander Gladysh once stated:

>
> 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 about:

{
  { true  , "OK" } ,
  { false , error_value } ,
  { true , 4 }
}

  -spc



Reply | Threaded
Open this post in threaded view
|

Re: Error handling strategy for Redis multi-bulk replies, in context of Lua bindings

Pierre Chapuis
 On Thu, 24 Mar 2011 01:33:41 -0400, Sean Conner wrote:

>> 1. OK
>> 2. (error) ERR Operation against a key holding the wrong kind of
>> value
>> 3. (integer) 4

> {
>   { true  , "OK" } ,
>   { false , error_value } ,
>   { true , 4 }
> }

 Or even:

 {
   { "status", "OK" },
   { "error", error_value },
   { "integer", 4 }
 }

 Or better imo:

 {
   { "OK", error_value, 4 },
   { "status", "error", "integer" }
 }

--
 Pierre 'catwell' Chapuis

Reply | Threaded
Open this post in threaded view
|

Re: Error handling strategy for Redis multi-bulk replies, in context of Lua bindings

Alexander Gladysh
In reply to this post by Robert G. Jakabosky
On Thu, Mar 24, 2011 at 05:52, Robert G. Jakabosky
<[hidden email]> wrote:
> On Wednesday 23, Alexander Gladysh wrote:

>> 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
>> }

>> P.S. Note that "OK" is a status reply (REDIS_REPLY_STATUS), not a
>> string (REDIS_REPLY_STRING). I'd like to separate those two as well,
>> but this is of much less priority (I think).

> I would wrap status/error replies in a status userdata object with a is_error
> field/method.  For string/number reply values convert them to basic lua
> string/numbers.

Interesting idea. I'm trying to imagine how the user's code would look
like. Wouldn't it be too cumbersome to work with?

Alexander.

Reply | Threaded
Open this post in threaded view
|

Re: Error handling strategy for Redis multi-bulk replies, in context of Lua bindings

Alexander Gladysh
In reply to this post by Pierre Chapuis
On Thu, Mar 24, 2011 at 09:38, Pierre Chapuis <[hidden email]> wrote:
> On Thu, 24 Mar 2011 01:33:41 -0400, Sean Conner wrote:

>>> 1. OK
>>> 2. (error) ERR Operation against a key holding the wrong kind of value
>>> 3. (integer) 4

>> {
>>  { true  , "OK" } ,
>>  { false , error_value } ,
>>  { true , 4 }
>> }

> Or even:

> {
>  { "status", "OK" },
>  { "error", error_value },
>  { "integer", 4 }
> }

> Or better imo:

> {
>  { "OK", error_value, 4 },
>  { "status", "error", "integer" }
> }

In this case, why the outer table? Make it two return values.

However — is this comfortable to work with from the user's point of view?

Alexander.

Reply | Threaded
Open this post in threaded view
|

Re: Error handling strategy for Redis multi-bulk replies, in context of Lua bindings

Pierre Chapuis
 On Thu, 24 Mar 2011 14:53:57 +0300, Alexander Gladysh wrote:

>> {
>>  { "OK", error_value, 4 },
>>  { "status", "error", "integer" }
>> }

> In this case, why the outer table? Make it two return values.

 That's what I actually had on my mine.

> However — is this comfortable to work with from the user's point of
> view?

 I think so. If you don't need error handling you simply don't use the
 second value, and if you do you go:

 local res,err = redis_call()
 for i=1,#err do
   if err[i] == "error" then
     ...
   else
     ...
   end
 end

--
 Pierre 'catwell' Chapuis

Reply | Threaded
Open this post in threaded view
|

Re: Error handling strategy for Redis multi-bulk replies, in context of Lua bindings

Jerome Vuarand
In reply to this post by Alexander Gladysh
2011/3/24 Alexander Gladysh <[hidden email]>:

> 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)

Reply | Threaded
Open this post in threaded view
|

Re: Error handling strategy for Redis multi-bulk replies, in context of Lua bindings

Alexander Gladysh
On Thu, Mar 24, 2011 at 17:09, Jerome Vuarand <[hidden email]> wrote:
> 2011/3/24 Alexander Gladysh <[hidden email]>:

>> 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.)

>> 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)

I just bind hiredis redisCommandArgv function directly. All higher
level stuff (like actual command names and argument validation) is
outside of the scope of this particular module. (I do want to write a
convenience high level Lua wrapper module later, but that is another
story.)

I would like to avoid creating an userdata per request, as I feel that
it would be too much overhead in both speed and code complexity
(complexity being the main reason here). So, unless there is some
clever way to do what you suggest that I do not see, I guess, I have
to stick to returning all data from exec() call.

Alexander.

Reply | Threaded
Open this post in threaded view
|

Re: Error handling strategy for Redis multi-bulk replies, in context of Lua bindings

Alexander Gladysh
In reply to this post by Alexander Gladysh
On Thu, Mar 24, 2011 at 14:52, Alexander Gladysh <[hidden email]> wrote:
> On Thu, Mar 24, 2011 at 05:52, Robert G. Jakabosky
> <[hidden email]> wrote:
>> On Wednesday 23, Alexander Gladysh wrote:

>>> 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
>>> }

>>> P.S. Note that "OK" is a status reply (REDIS_REPLY_STATUS), not a
>>> string (REDIS_REPLY_STRING). I'd like to separate those two as well,
>>> but this is of much less priority (I think).

>> I would wrap status/error replies in a status userdata object with a is_error
>> field/method.  For string/number reply values convert them to basic lua
>> string/numbers.

> Interesting idea. I'm trying to imagine how the user's code would look
> like. Wouldn't it be too cumbersome to work with?

Also, I'm concerned by the overhead — status replies are common in the
protocol, and creating an userdata per each can be too much (strings
should be cheaper, and, besides, users do not need to look into status
codes that often, I think).

Alexander.

Reply | Threaded
Open this post in threaded view
|

Re: Error handling strategy for Redis multi-bulk replies, in context of Lua bindings

Jerome Vuarand
2011/3/24 Alexander Gladysh <[hidden email]>:

>>> I would wrap status/error replies in a status userdata object with a is_error
>>> field/method.  For string/number reply values convert them to basic lua
>>> string/numbers.
>
>> Interesting idea. I'm trying to imagine how the user's code would look
>> like. Wouldn't it be too cumbersome to work with?
>
> Also, I'm concerned by the overhead — status replies are common in the
> protocol, and creating an userdata per each can be too much (strings
> should be cheaper, and, besides, users do not need to look into status
> codes that often, I think).

To avoid clash with strings, you can have your status codes be
userdata without allocating one at each request. Just keep a redis.ok
value that you return, and client code can write "if status==redis.ok
then end".

That being said, I think (please correct me if I'm wrong) that string
allocation is not cheaper in terms of execution speed than userdata
allocation, unless most of the strings are expected to be already
interned (which completely depends on the data your client will put in
your redis db).

Reply | Threaded
Open this post in threaded view
|

Re: Error handling strategy for Redis multi-bulk replies, in context of Lua bindings

Alexander Gladysh
On Thu, Mar 24, 2011 at 19:57, Jerome Vuarand <[hidden email]> wrote:
> 2011/3/24 Alexander Gladysh <[hidden email]>:
>>>> I would wrap status/error replies in a status userdata object with a is_error
>>>> field/method.  For string/number reply values convert them to basic lua
>>>> string/numbers.

>>> Interesting idea. I'm trying to imagine how the user's code would look
>>> like. Wouldn't it be too cumbersome to work with?

>> Also, I'm concerned by the overhead — status replies are common in the
>> protocol, and creating an userdata per each can be too much (strings
>> should be cheaper, and, besides, users do not need to look into status
>> codes that often, I think).

> To avoid clash with strings, you can have your status codes be
> userdata without allocating one at each request. Just keep a redis.ok
> value that you return, and client code can write "if status==redis.ok
> then end".

Have to do strcmpi() or something for this in C code first. (Not a big problem.)

> That being said, I think (please correct me if I'm wrong) that string
> allocation is not cheaper in terms of execution speed than userdata
> allocation, unless most of the strings are expected to be already
> interned (which completely depends on the data your client will put in
> your redis db).

Well, as I understand, in this case, it does not depend on data in db
— we're discussing status codes.

There are (I think, please correct me) two common status replies
(REDIS_REPLY_STATUS) in Redis: OK and QUEUED (for multi/exec).

I could cache these two, and if I encounter anything else, I'll just
allocate a new one. (Actually, I'll cache a Redis NIL as well — looks
like it needs to be separate from Lua nil — not so sure about this
though.)

But the question is how to actually write the thing then:

1. Where is the best place to store actual hiredis.OK and
hiredis.QUEUED values, so they are easily accessible by the C code?

2. What is the best way to handle REDIS_REPLY_STATUS case? Just bite
the bullet and do two string comparisons? Or does anyone see something
more clever?

Thanks,
Alexander.

Reply | Threaded
Open this post in threaded view
|

Re: Error handling strategy for Redis multi-bulk replies, in context of Lua bindings

Jerome Vuarand
2011/3/24 Alexander Gladysh <[hidden email]>:

> On Thu, Mar 24, 2011 at 19:57, Jerome Vuarand <[hidden email]> wrote:
>> 2011/3/24 Alexander Gladysh <[hidden email]>:
>>>>> I would wrap status/error replies in a status userdata object with a is_error
>>>>> field/method.  For string/number reply values convert them to basic lua
>>>>> string/numbers.
>
>>>> Interesting idea. I'm trying to imagine how the user's code would look
>>>> like. Wouldn't it be too cumbersome to work with?
>
>>> Also, I'm concerned by the overhead — status replies are common in the
>>> protocol, and creating an userdata per each can be too much (strings
>>> should be cheaper, and, besides, users do not need to look into status
>>> codes that often, I think).
>
>> To avoid clash with strings, you can have your status codes be
>> userdata without allocating one at each request. Just keep a redis.ok
>> value that you return, and client code can write "if status==redis.ok
>> then end".
>
> Have to do strcmpi() or something for this in C code first. (Not a big problem.)

You can use Lua to avoid the strcmpi. Just push the string, and index
the table where you put the userdata (see below).

>> That being said, I think (please correct me if I'm wrong) that string
>> allocation is not cheaper in terms of execution speed than userdata
>> allocation, unless most of the strings are expected to be already
>> interned (which completely depends on the data your client will put in
>> your redis db).
>
> Well, as I understand, in this case, it does not depend on data in db
> — we're discussing status codes.
>
> There are (I think, please correct me) two common status replies
> (REDIS_REPLY_STATUS) in Redis: OK and QUEUED (for multi/exec).
>
> I could cache these two, and if I encounter anything else, I'll just
> allocate a new one. (Actually, I'll cache a Redis NIL as well — looks
> like it needs to be separate from Lua nil — not so sure about this
> though.)
>
> But the question is how to actually write the thing then:
>
> 1. Where is the best place to store actual hiredis.OK and
> hiredis.QUEUED values, so they are easily accessible by the C code?

One common way to share such constants between the C implementation
and the Lua client code, is to put them in the module table. To get
easy access to the module table, a common practice is to have the
module be the function environment of your lua_CFunction-s. To do
that, in the luaopen_<modname> function, first create the module table
(1), then duplicate the reference (2), make the table the current
environment (3), and register your functions (4):

static luaL_Reg empty[] = {{0, 0}};
static luaL_Reg functions[] = {
  /* put your binding there */
  {0, 0}
};

int luaopen_mymodule(lua_State* L)
{
  /* init the module */
  luaL_register(L, lua_tostring(L, 1), empty); /* (1) */
  /* set as fenv */
  lua_pushvalue(L, -1); /* (2) */
  lua_replace(L, LUA_ENVIRONINDEX); /* (3) */
  /* register the functions */
  luaL_register(L, 0, functions); /* (4) */
  /* create ok and queued (zero-sized) udata */
  lua_newuserdata(L, 0);
  lua_setfield(L, -2, "ok");
  lua_newuserdata(L, 0);
  lua_setfield(L, -2, "queued");
  return 0;
}

> 2. What is the best way to handle REDIS_REPLY_STATUS case? Just bite
> the bullet and do two string comparisons? Or does anyone see something
> more clever?

So redis gives you a C string ? Just use it as a key in the module
table, which you previously set as all your lua_CFunction-s
environment:

{
  const char* redis_result;
  ... /* get a value for redis_result */
  lua_getfield(L, LUA_ENVIRONINDEX, redis_result);
  return 1;
}

Reply | Threaded
Open this post in threaded view
|

Re: Error handling strategy for Redis multi-bulk replies, in context of Lua bindings

Alexander Gladysh
On Thu, Mar 24, 2011 at 20:40, Jerome Vuarand <[hidden email]> wrote:
> 2011/3/24 Alexander Gladysh <[hidden email]>:
>> On Thu, Mar 24, 2011 at 19:57, Jerome Vuarand <[hidden email]> wrote:
>>> 2011/3/24 Alexander Gladysh <[hidden email]>:
>>>>>> I would wrap status/error replies in a status userdata object with a is_error
>>>>>> field/method.  For string/number reply values convert them to basic lua
>>>>>> string/numbers.

>>>> Also, I'm concerned by the overhead — status replies are common in the
>>>> protocol, and creating an userdata per each can be too much (strings
>>>> should be cheaper, and, besides, users do not need to look into status
>>>> codes that often, I think).

>>> To avoid clash with strings, you can have your status codes be
>>> userdata without allocating one at each request. Just keep a redis.ok
>>> value that you return, and client code can write "if status==redis.ok
>>> then end".

>> Have to do strcmpi() or something for this in C code first. (Not a big problem.)

> You can use Lua to avoid the strcmpi. Just push the string, and index
> the table where you put the userdata (see below).

Not sure if strcmpi is faster than string interning — but this
argument reeks of premature optimization. I will go here for more
robust design.

>> There are (I think, please correct me) two common status replies
>> (REDIS_REPLY_STATUS) in Redis: OK and QUEUED (for multi/exec).

>> But the question is how to actually write the thing then:

>> 1. Where is the best place to store actual hiredis.OK and
>> hiredis.QUEUED values, so they are easily accessible by the C code?

> One common way to share such constants between the C implementation
> and the Lua client code, is to put them in the module table.

Constants definitely should be in module table, since this is the best
way to make them available for Lua code.

> To get
> easy access to the module table, a common practice is to have the
> module be the function environment of your lua_CFunction-s. To do
> that, in the luaopen_<modname> function, first create the module table
> (1), then duplicate the reference (2), make the table the current
> environment (3), and register your functions (4):

<...>

>  lua_replace(L, LUA_ENVIRONINDEX); /* (3) */

This will not work in 5.2 anymore. (Not that I'm that much eager to
support it, but...)

>> 2. What is the best way to handle REDIS_REPLY_STATUS case? Just bite
>> the bullet and do two string comparisons? Or does anyone see something
>> more clever?

> So redis gives you a C string ?

Yep.

> Just use it as a key in the module
> table, which you previously set as all your lua_CFunction-s
> environment:

> {
>  const char* redis_result;
>  ... /* get a value for redis_result */
>  lua_getfield(L, LUA_ENVIRONINDEX, redis_result);
>  return 1;
> }

Looks like that, with some metatable magic, I even can create status
userdata on demand and not bother with pre-caching it.

Thanks,
Alexander.

Reply | Threaded
Open this post in threaded view
|

Re: Error handling strategy for Redis multi-bulk replies, in context of Lua bindings

Jerome Vuarand
2011/3/24 Alexander Gladysh <[hidden email]>:
> On Thu, Mar 24, 2011 at 20:40, Jerome Vuarand <[hidden email]> wrote:
>>  lua_replace(L, LUA_ENVIRONINDEX); /* (3) */
>
> This will not work in 5.2 anymore. (Not that I'm that much eager to
> support it, but...)

In 5.2 you have to use upvalues instead. Thankfully, there is a
luaL_register-like function that let you push an array of functions
sharing an upvalue (the module table), which was a little more
complicated to do in 5.1.

>>> 2. What is the best way to handle REDIS_REPLY_STATUS case? Just bite
>>> the bullet and do two string comparisons? Or does anyone see something
>>> more clever?
>
>> So redis gives you a C string ?
>
> Yep.
>
>> Just use it as a key in the module
>> table, which you previously set as all your lua_CFunction-s
>> environment:
>
>> {
>>  const char* redis_result;
>>  ... /* get a value for redis_result */
>>  lua_getfield(L, LUA_ENVIRONINDEX, redis_result);
>>  return 1;
>> }
>
> Looks like that, with some metatable magic, I even can create status
> userdata on demand and not bother with pre-caching it.

This qualifies as premature optimization too ;-)

If you only have a few status codes, the metatable + metamethod
creation may just cost more that pre-caching the values.

Reply | Threaded
Open this post in threaded view
|

Re: Error handling strategy for Redis multi-bulk replies, in context of Lua bindings

Alexander Gladysh
On Thu, Mar 24, 2011 at 21:34, Jerome Vuarand <[hidden email]> wrote:
> 2011/3/24 Alexander Gladysh <[hidden email]>:
>> On Thu, Mar 24, 2011 at 20:40, Jerome Vuarand <[hidden email]> wrote:

>>> Just use it as a key in the module
>>> table, which you previously set as all your lua_CFunction-s
>>> environment:

>>> {
>>>  const char* redis_result;
>>>  ... /* get a value for redis_result */
>>>  lua_getfield(L, LUA_ENVIRONINDEX, redis_result);
>>>  return 1;
>>> }

>> Looks like that, with some metatable magic, I even can create status
>> userdata on demand and not bother with pre-caching it.

> This qualifies as premature optimization too ;-)

> If you only have a few status codes, the metatable + metamethod
> creation may just cost more that pre-caching the values.

No, that is not about the speed here. I think that, probably, this
will make the code look better. We'll see :-)

Alexander.

Reply | Threaded
Open this post in threaded view
|

Re: Error handling strategy for Redis multi-bulk replies, in context of Lua bindings

Alexander Gladysh
On Thu, Mar 24, 2011 at 21:38, Alexander Gladysh <[hidden email]> wrote:
> On Thu, Mar 24, 2011 at 21:34, Jerome Vuarand <[hidden email]> wrote:
>> 2011/3/24 Alexander Gladysh <[hidden email]>:
>>> On Thu, Mar 24, 2011 at 20:40, Jerome Vuarand <[hidden email]> wrote:

>>>> Just use it as a key in the module
>>>> table, which you previously set as all your lua_CFunction-s
>>>> environment:

>>>> {
>>>>  const char* redis_result;
>>>>  ... /* get a value for redis_result */
>>>>  lua_getfield(L, LUA_ENVIRONINDEX, redis_result);
>>>>  return 1;
>>>> }

>>> Looks like that, with some metatable magic, I even can create status
>>> userdata on demand and not bother with pre-caching it.

>> This qualifies as premature optimization too ;-)

>> If you only have a few status codes, the metatable + metamethod
>> creation may just cost more that pre-caching the values.

> No, that is not about the speed here. I think that, probably, this
> will make the code look better. We'll see :-)

Note also that I do not know ahead of time exactly what status string
Redis will send me. So I will have to extend the table in run-time
anyway.

Alexander.