FAQ

[Redis] defining Lua functions

Xavier Noria
Dec 13, 2012 at 12:06 pm
I have some data packed with msgpack, whose access from within Lua I'd like
to encapsulate. Is that possible?

--
You received this message because you are subscribed to the Google Groups "Redis DB" group.
To view this discussion on the web visit https://groups.google.com/d/msg/redis-db/-/jmZat4vOPtgJ.
To post to this group, send email to redis-db@googlegroups.com.
To unsubscribe from this group, send email to redis-db+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/redis-db?hl=en.
reply

Search Discussions

9 responses

  • Josiah Carlson at Dec 13, 2012 at 4:39 pm
    Redis' Lua runtime includes msgpack functionality. Looking around a
    bit, I believe you can use cmsgpack.pack() and cmsgpack.unpack() .

    - Josiah
    On Thu, Dec 13, 2012 at 4:06 AM, Xavier Noria wrote:
    I have some data packed with msgpack, whose access from within Lua I'd like
    to encapsulate. Is that possible?

    --
    You received this message because you are subscribed to the Google Groups
    "Redis DB" group.
    To view this discussion on the web visit
    https://groups.google.com/d/msg/redis-db/-/jmZat4vOPtgJ.
    To post to this group, send email to redis-db@googlegroups.com.
    To unsubscribe from this group, send email to
    redis-db+unsubscribe@googlegroups.com.
    For more options, visit this group at
    http://groups.google.com/group/redis-db?hl=en.
    --
    You received this message because you are subscribed to the Google Groups "Redis DB" group.
    To post to this group, send email to redis-db@googlegroups.com.
    To unsubscribe from this group, send email to redis-db+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/redis-db?hl=en.
  • Xavier Noria at Dec 13, 2012 at 5:01 pm
    El dijous 13 de desembre de 2012 17:31:15 UTC+1, Josiah Carlson va escriure:

    Redis' Lua runtime includes msgpack functionality. Looking around a
    bit, I believe you can use cmsgpack.pack() and cmsgpack.unpack() .
    Yes, I am already using that lib, which the docs guarantee to have
    available.

    What I'd like to do is to encapsulate those calls within Lua, rather than
    doing manual unpacks all over the place.


    --
    You received this message because you are subscribed to the Google Groups "Redis DB" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/redis-db/-/t-bQyQr0QigJ.
    To post to this group, send email to redis-db@googlegroups.com.
    To unsubscribe from this group, send email to redis-db+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/redis-db?hl=en.
  • Pierre Chapuis at Dec 13, 2012 at 4:59 pm
    Le jeudi 13 décembre 2012 17:35:28 UTC+1, Xavier Noria a écrit :
    El dijous 13 de desembre de 2012 17:31:15 UTC+1, Josiah Carlson va
    escriure:

    Yes, I am already using that lib, which the docs guarantee to have
    available.

    What I'd like to do is to encapsulate those calls within Lua, rather than
    doing manual unpacks all over the place.
    You just mean writing a function like that?

    local getobj = function(k)
    local d = redis.call("get",k)
    return d and cmsgpack.unpack(d) or nil
    end

    If not then I don't really understand...

    --
    You received this message because you are subscribed to the Google Groups "Redis DB" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/redis-db/-/503pOy9ep7AJ.
    To post to this group, send email to redis-db@googlegroups.com.
    To unsubscribe from this group, send email to redis-db+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/redis-db?hl=en.
  • Xavier Noria at Dec 14, 2012 at 6:01 am
    El dijous 13 de desembre de 2012 17:59:17 UTC+1, Pierre Chapuis va escriure:

    You just mean writing a function like that?
    local getobj = function(k)
    local d = redis.call("get",k)
    return d and cmsgpack.unpack(d) or nil
    end

    If not then I don't really understand...

    Let's say you have a series of scripts loaded, and some of them access to
    that structure. I would like to be able to define a function that I can use
    in any of those scripts to encapsulate the unpack details.

    I guess the answer is that is not possible.

    These scripts are loaded from Ruby, I guess a workaround would be to inject
    the function definition in all of them as local variables.





    --
    You received this message because you are subscribed to the Google Groups "Redis DB" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/redis-db/-/h1xhxipsi7kJ.
    To post to this group, send email to redis-db@googlegroups.com.
    To unsubscribe from this group, send email to redis-db+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/redis-db?hl=en.
  • Josiah Carlson at Dec 14, 2012 at 6:54 pm
    At Redisconf, Nathan Fritz mentioned that scripts loaded are actually
    accessible inside of Redis using a name derived from the hash. There
    were questions about whether that behavior would persist long-term,
    but for right now, you should be able to execute it via 'f_<hash>'
    inside Lua.

    - Josiah
    On Thu, Dec 13, 2012 at 10:01 PM, Xavier Noria wrote:
    El dijous 13 de desembre de 2012 17:59:17 UTC+1, Pierre Chapuis va escriure:

    You just mean writing a function like that?

    local getobj = function(k)
    local d = redis.call("get",k)
    return d and cmsgpack.unpack(d) or nil
    end

    If not then I don't really understand...


    Let's say you have a series of scripts loaded, and some of them access to
    that structure. I would like to be able to define a function that I can use
    in any of those scripts to encapsulate the unpack details.

    I guess the answer is that is not possible.

    These scripts are loaded from Ruby, I guess a workaround would be to inject
    the function definition in all of them as local variables.





    --
    You received this message because you are subscribed to the Google Groups
    "Redis DB" group.
    To view this discussion on the web visit
    https://groups.google.com/d/msg/redis-db/-/h1xhxipsi7kJ.

    To post to this group, send email to redis-db@googlegroups.com.
    To unsubscribe from this group, send email to
    redis-db+unsubscribe@googlegroups.com.
    For more options, visit this group at
    http://groups.google.com/group/redis-db?hl=en.
    --
    You received this message because you are subscribed to the Google Groups "Redis DB" group.
    To post to this group, send email to redis-db@googlegroups.com.
    To unsubscribe from this group, send email to redis-db+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/redis-db?hl=en.
  • Xavier Noria at Jan 14, 2013 at 5:03 pm
    El dijous 13 de desembre de 2012 13:06:53 UTC+1, Xavier Noria va escriure:

    I have some data packed with msgpack, whose access from within Lua I'd like
    to encapsulate. Is that possible?

    For the archives. In the end I used Ruby string interpolation.

    I have a couple macros to define Lua scripts within the classes they are
    related to. One for defining the script:

    def self.def_script(name, code)
    sha1 = redis.script(:load, <<-LUA)
    local contacts_key_for = function(user_id) return 'contacts:' ..
    user_id end
    local timeline_key_for = function(user_id) return 'timeline:' ..
    user_id end

    #{code}
    LUA
    scripts[name] = {code: code, sha1: sha1}
    end

    and another one to invoke it with some robustness in case Redis got
    rebooted or lost the scripts cache somehow:

    def eval_script(name, keys=[], argv=[])
    if script = scripts[name]
    begin
    redis.evalsha(script[:sha1], keys, argv)
    rescue Redis::CommandError => e
    if e.message.include?('NOSCRIPT')
    redis.script(:load, script[:code])
    retry
    else
    raise
    end
    end
    else
    raise ArgumentError.new("unknown script: #{name}")
    end
    end

    Relevant to this thread is the first one. Since all script definitions go
    through that macro, we just inject functions we want in scope at that point.

    --
    You received this message because you are subscribed to the Google Groups "Redis DB" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/redis-db/-/jT2BHqX2-GgJ.
    To post to this group, send email to redis-db@googlegroups.com.
    To unsubscribe from this group, send email to redis-db+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/redis-db?hl=en.
  • Xavier Noria at Jan 14, 2013 at 5:11 pm
    El dijous 13 de desembre de 2012 13:06:53 UTC+1, Xavier Noria va escriure:

    I have some data packed with msgpack, whose access from within Lua I'd like
    to encapsulate. Is that possible?

    For the archives, I ended up using Ruby string interpolation to accomplish
    this.

    I have a macro to define Lua scripts in the body of the Ruby classes they
    are related to:

    def self.def_script(name, code)
    code = <<-LUA
    local contacts_key_for = function(user_id) return 'contacts:' ..
    user_id end
    local timeline_key_for = function(user_id) return 'timeline:' ..
    user_id end
    ...

    #{code}
    LUA

    sha1 = redis.script(:load, code)
    scripts[name] = {code: code, sha1: sha1}
    end

    and since all definitions go through that macro, we just inject functions
    to have them available everywhere.

    To complete the feedback, there is a companying method to invoke those
    scripts by name, with some robustness in case Redis lost his scripts cache:

    def eval_script(name, keys=[], argv=[])
    if script = scripts[name]
    begin
    redis.evalsha(script[:sha1], keys, argv)
    rescue Redis::CommandError => e
    if e.message.include?('NOSCRIPT')
    redis.script(:load, script[:code])
    retry
    else
    raise
    end
    end
    else
    raise ArgumentError.new("unknown script: #{name}")
    end
    end

    Xavier


    --
    You received this message because you are subscribed to the Google Groups "Redis DB" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/redis-db/-/SiGuK-iOhbwJ.
    To post to this group, send email to redis-db@googlegroups.com.
    To unsubscribe from this group, send email to redis-db+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/redis-db?hl=en.
  • Matt Keranen at Jan 15, 2013 at 7:28 pm
    http://blog.crunchmagic.com/post/35642709362/functions-in-redis-scripts
    On Thursday, December 13, 2012 7:06:53 AM UTC-5, Xavier Noria wrote:

    I have some data packed with msgpack, whose access from within Lua I'd
    like to encapsulate. Is that possible?
    --
    You received this message because you are subscribed to the Google Groups "Redis DB" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/redis-db/-/vkdlHs-3qaUJ.
    To post to this group, send email to redis-db@googlegroups.com.
    To unsubscribe from this group, send email to redis-db+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/redis-db?hl=en.
  • Xavier Noria at Jan 16, 2013 at 2:58 pm
    El dimarts 15 de gener de 2013 20:28:51 UTC+1, Matt Keranen va escriure:

    http://blog.crunchmagic.com/post/35642709362/functions-in-redis-scripts


    Yep, that explains how to define a lambda in a script.

    What I was trying to solve was to share functions across all my Lua
    scripts, to have kind of a global namespace. The solution has been to
    inject the lambdas via a macro all my code uses to load the scripts.

    --
    You received this message because you are subscribed to the Google Groups "Redis DB" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/redis-db/-/AcmzbwYOtrsJ.
    To post to this group, send email to redis-db@googlegroups.com.
    To unsubscribe from this group, send email to redis-db+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/redis-db?hl=en.

Related Discussions

Discussion Navigation
viewthread | post