lua-users home
lua-l archive

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


On Thu, Mar 24, 2011 at 20:40, Jerome Vuarand <jerome.vuarand@gmail.com> wrote:
> 2011/3/24 Alexander Gladysh <agladysh@gmail.com>:
>> On Thu, Mar 24, 2011 at 19:57, Jerome Vuarand <jerome.vuarand@gmail.com> wrote:
>>> 2011/3/24 Alexander Gladysh <agladysh@gmail.com>:
>>>>>> 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.