January 10, 2009

Introducing merle : an Erlang memcached client.

The last couple days I have been putting together a memcached client for Erlang called merle. At the moment it supports the gambit of memcached commands (minus the noreply option). While it is very much a work in progress and under heavy development it is fairly usable. The latest code is available on github. Here’s an example of its usage:

[user@host ebin]$ erl
Erlang (BEAM) emulator version 5.6.5 [source] [64-bit] [smp:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.6.5 (abort with ^G)
1> merle:start_link(“localhost”, 11211).
{ok,<0.35.0>}
2> merle:memcache_set(“123″, “1″, “0″, “this is some data”).
<<”STORED\r\n”>>
ok
3> merle:memcache_get(“123″).
<<”VALUE 123 1 17\r\nthis is some data\r\nEND\r\n”>>
ok

Ladies and gentlemen, Mr. Merle Haggard.

YouTube Preview Image

14 Comments

  1. ayrnieu Jan 11, 2009 3:30 am

    Here’s what may be a fast way to get at the data:

    skip(B, X) -> skip(B, X, 8).
    skip(B, X, Len) ->
    case B of
    <> -> Rest;
    <> -> skip(Rest, X, Len)
    end.

    chomp(B, Bytes) ->
    S = size(B) – Bytes,
    <> = B,
    R.

    dememcache(B) -> chomp(skip(B, $\n), size(<>)).

  2. ayrnieu Jan 11, 2009 3:31 am

    well, that certainly failed. I’ll reply at reddit/r/erlang.

  3. joe Jan 11, 2009 12:14 pm

    Thanks for the code, I’ll check it out.

  4. Matt Williamson Jan 13, 2009 9:02 am

    Very nice. I’ll be checking this out today.

  5. eugen32 Jan 16, 2009 4:57 pm

    code is bearable. music sucks.

  6. developers.hover.in » Somethings to rejoice about May 18, 2009 12:25 am
  7. Carlos Jun 07, 2009 2:34 am

    Hi Joe! I would like to share with you the early implementation of a libmemcached wrapper for Erlang I’ve just published in Google Code. Any ideas to improve it are welcome! :)

  8. Francesco Aug 05, 2009 5:12 am

    Hi, I’m trying to use your memcache client to store data into sparrow. Storing with set seems to work fine, but if I try to get data from a php script I don’t seem to be getting anything. I suppose it is due to this
    “Notes:
    * Uses term_to_binary and binary_to_term to serialize/deserialize Erlang terms before sending/receiving them. This
    allows for native Erlang terms to be returned from memcached but doesn’t play well using other languages after setting
    values with merle or using merle to get values set by other languages.”

    Is there any workaround to this? I’m not skilled in erlang tough, but I have to store into memcache messages coming through ejabberd :(

  9. joe Aug 05, 2009 9:01 am

    Check out this fork http://github.com/dreid/merle/tree/master I think it does what you want it to.

  10. Francesco Aug 06, 2009 1:10 am

    I checked that out Joe, but it seems to be serializing/deserializing anyway, I don’t find any difference with the first implementation I tried… where am I wrong?

  11. joe Aug 06, 2009 3:35 pm

    Check out the handle_call for “set” you should be able to use “raw” mode. Something like this:

    merle:set(Key, {raw, Value})

  12. Francesco Aug 10, 2009 12:03 am

    I tried that, but I get this error :

    ** Generic server {local,merle} terminating
    ** Last message in was {set,{“coda1″,”6049″,”0″,
    {raw,”stringa di prova da non serializzare”}}}
    ** When Server state == #Port
    ** Reason for termination ==
    ** {badarg,[{erlang,size,["stringa di prova da non serializzare"]},
    {merle,handle_call,3},
    {gen_server2,handle_msg,7},
    {proc_lib,init_p_do_apply,3}]}
    ** exception exit: badarg
    in function size/1
    called as size(“stringa di prova da non serializzare”)
    in call from merle:handle_call/3
    in call from gen_server2:handle_msg/7
    in call from proc_lib:init_p_do_apply/3

    when I try to do merle:set(Key, {raw,”stringa di prova da non serializzare”}).

    If i try to do something like this merle:set(Key, {raw,Tuple}), with a tuple inside Tuple (obviously), it fails with this error :

    =ERROR REPORT==== 10-Aug-2009::09:58:59 ===
    ** Generic server {local,merle} terminating
    ** Last message in was {set,{“coda1″,”6049″,”0″,
    {raw,{tupla,”stringa”,123123,”numero”}}}}
    ** When Server state == #Port
    ** Reason for termination ==
    ** {badarg,[{merle,send_storage_cmd,3},
    {merle,handle_call,3},
    {gen_server2,handle_msg,7},
    {proc_lib,init_p_do_apply,3}]}
    ** exception exit: badarg
    in function merle:send_storage_cmd/3
    in call from merle:handle_call/3
    in call from gen_server2:handle_msg/7
    in call from proc_lib:init_p_do_apply/3

  13. Francesco Aug 10, 2009 12:12 am

    I now just tried something like this :

    merle:set(“coda1″, {raw, randomatom, “prova stringa di prova”}).

    And it correctly inserts data. If I do a merle:getkey it works. But if I try to read that key from php I only get a false in return.

    Guess I’ll have to abandon the idea of using ejabberd :(

  14. joe Aug 11, 2009 3:28 pm

    Looks like you are probably having issues marshaling the data from memcached. In other words PHP doesn’t know how to read Erlang tuple. You may want to contact the fork author and see how he was doing it. I think he was using python though.

Leave a Comment

(required)

(will not be published) (required)