[erlang-questions] Replicated messaging in Erlang?

78 views
Skip to first unread message

Adam Warski

unread,
Jul 27, 2012, 6:47:31 AM7/27/12
to erlang-q...@erlang.org
Hello,

I've been looking at the Erlang ecosystem, and coming from a Java world, I am wondering what is the "Erlang way" to implement the following.

The use case is very simple: I want to receive requests from users, and later process them asynchronously. However I want to be sure that if a request is received, it will be safe from single-node crashes, in other words, I want requests to be replicated across my cluster.

In Java I would implement it using a replicated message queue. However RabbitMQ doesn't have replicated queues, only the meta-data is clustered (as far as I know). Mnesia has replication, but then it is a database, not a queue (although you could probably implement a mq ontop od that, but I didn't see anybody doing that).

So how would you implememt this in Erlang? :)

Regards,
Adam Warski
_______________________________________________
erlang-questions mailing list
erlang-q...@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions

Francesco Mazzoli

unread,
Jul 27, 2012, 7:19:30 AM7/27/12
to erlang-q...@erlang.org
At Fri, 27 Jul 2012 12:47:31 +0200,
Adam Warski wrote:
> However RabbitMQ doesn't have replicated queues, only the meta-data is
> clustered (as far as I know).

RabbitMQ *does* have replicated (High Availability) queues:
http://www.rabbitmq.com/ha.html .

--
Francesco * Often in error, never in doubt

CGS

unread,
Jul 27, 2012, 7:24:29 AM7/27/12
to Adam Warski, erlang-q...@erlang.org
Hi Adam,

If I understood correctly your question, there are two points there:
1. how you can replicate a message;
2. how you can be sure that the message is received.

If that is the case, here are few simple answers (hopefully, more skilled Erlang users will come with better ideas/solutions):

1. Take a look at gproc or any equivalent implementation.

2. That depends on how the message is sent, but the general solution is to have a reply from the receiver. Here are two simple solutions for doing that:

a) Message sent via threads messaging (Pid ! MyMessage):
-> sender: ReceiverPid ! {self(), MyMessage}
-> receiver listener (basics only):
receive
    Message -> {SenderPid, SenderMessage} = Message, SenderPid ! received
    ...
end
or you can add SenderPid in the group of receivers.

b) Message sent via TCP connection (for the receiver only; the sender should have also a listener to be able to receive the answer):
listen_socket(Socket) ->
    case gen_tcp:recv(Socket, 0) of
          {ok,Data} ->
              gen_tcp:send(Socket,<<"received">>),
              listen_socket(Socket);
         ...
    end.

These are only few basic options. Of course, there are many other options (e.g., monitoring your receiver). I resume my answer to a simple one. Take care of the length of the queue (if you need a personalized queue, I suggest gen_fsm).

I hope this answer helps and if I misunderstood your problem, I kindly ask you to ignore my answer.

CGS

Adam Warski

unread,
Jul 27, 2012, 2:14:39 PM7/27/12
to Adam Rutkowski, erlang-q...@erlang.org
Thanks, not sure how I could have missed that :)

So, you would use mirrored queues in that use-case?

Regards,
Adam Warski

On 27 lip 2012, at 13:01, Adam Rutkowski <adam.ru...@jtendo.com> wrote:

>
> On Jul 27, 2012, at 12:47 PM, Adam Warski wrote:
>
>> However RabbitMQ doesn't have replicated queues, only the meta-data is clustered (as far as I know).
>
> How about mirrored queues?
>
> http://www.rabbitmq.com/ha.html
>
> --
> AR

Adam Warski

unread,
Jul 27, 2012, 2:27:41 PM7/27/12
to CGS, erlang-q...@erlang.org
Thank you for the answer,

On 27 lip 2012, at 13:24, CGS <cgsmc...@gmail.com> wrote:

> Hi Adam,
>
> If I understood correctly your question, there are two points there:
> 1. how you can replicate a message;
> 2. how you can be sure that the message is received.
>
> If that is the case, here are few simple answers (hopefully, more skilled Erlang users will come with better ideas/solutions):
>
> 1. Take a look at gproc or any equivalent implementation.

Thanks, looks quite big, but I'll try to dig through it. Though it's not only replicating the message, it's also consuming the message across the cluster once it is consumed on the master node, etc.

Tim Watson

unread,
Jul 28, 2012, 10:03:26 AM7/28/12
to Adam Warski, erlang-q...@erlang.org
Adam, please take some time to walk through the rabbitmq documentation - there's quite a lot of it! Rabbit supports replication using HA (master/slave mirror) queues, or federation for replicating over the WAN/Internet. This does exactly what you've asked for.

If you'd like to understand how it works, take a lot at gm.erl (guaranteed multicast) which is a fully asynchronous ring protocol developed independently at rabbit to support HA.

Cheers.
Tim

Adam Warski

unread,
Jul 30, 2012, 10:38:46 AM7/30/12
to Tim Watson, erlang-q...@erlang.org

> Adam, please take some time to walk through the rabbitmq documentation - there's quite a lot of it! Rabbit supports replication using HA (master/slave mirror) queues, or federation for replicating over the WAN/Internet. This does exactly what you've asked for.

I did some time ago, but either the docs got improved, or I just skipped a whole paragraph after reading "An exception to this are message queues, which by default reside on the node that created them, though they are visible and reachable from all nodes.". Anyway, all is clear now :).

> If you'd like to understand how it works, take a lot at gm.erl (guaranteed multicast) which is a fully asynchronous ring protocol developed independently at rabbit to support HA.

Thanks for the pointer!

Adam

--
Adam Warski

http://twitter.com/#!/adamwarski
http://www.softwaremill.com
http://www.warski.org
Reply all
Reply to author
Forward
0 new messages