Using Actors to send email inside a web app

229 views
Skip to first unread message

Paul Lambert

unread,
Apr 9, 2011, 9:58:38 PM4/9/11
to Akka User List
Hi,

I'm relatively new to actors / akka and would appreciate some
feedback / help modelling a little system. My basic problem (one which
I'm sure has been solved before by many) is that I want to send email
as a result of an action in a web app, but I want to do this
asynchronously (so that if a browser action generates say, 200 emails,
the user doesn't have to wait for those 200 emails to be sent).

Immediate I see three strategies:

1) have the request handler start an actor, send it the template and
recipient list and list it handle generating the emails, and sending
all of them.
pros: simple, cons: if something blows up while sending the second
email, all the rest get lost.
2) start an actor for every email to send (so a couple hundred
actors). Give each one a recipient and a message to send.
pros: no dependencies between messages, cons: might be slower
(creating every actor), have to create a new session for every message
(not just open a connection a pump all emails through it).
3) a combo: start 1 actor that receives everything, and then it
creates an actor to actually send every message.
pros: should be as fast as 1 and have no dependencies between message
send success. cons: more complex, maybe can't share session between
actors(?)

Thanks so much for listening to this. Does anyone have any thoughts or
suggestions?

Paul

Peter Veentjer

unread,
Apr 10, 2011, 3:58:21 AM4/10/11
to akka...@googlegroups.com
Hi Paul,

I have placed comments inline.

On Sun, Apr 10, 2011 at 3:58 AM, Paul Lambert <pa...@paulitex.com> wrote:
Hi,

I'm relatively new to actors / akka and would appreciate some
feedback / help modelling a little system. My basic problem (one which
I'm sure has been solved before by many) is that I want to send email
as a result of an action in a web app, but I want to do this
asynchronously (so that if a browser action generates say, 200 emails,
the user doesn't have to wait for those 200 emails to be sent).

Immediate I see three strategies:

1) have the request handler start an actor, send it the template and
recipient list and list it handle generating the emails, and sending
all of them.
pros: simple, cons: if something blows up while sending the second
email, all the rest get lost.

I see this problem very often. What you could do is to catch the exception,
and log it, and continue to the next. Perhaps after some threshold has been
reached you stop processing the batch.

All the failed messages could be placed in some kind of hospital (perhaps another
actor) that tries to resend them after some time.
 
2) start an actor for every email to send (so a couple hundred
actors). Give each one a recipient and a message to send.
pros: no dependencies between messages, cons: might be slower
(creating every actor), have to create a new session for every message
(not just open a connection a pump all emails through it).

I think the overhead will be in sending the email since a remote calls is orders
of magnitude more slower than in memory calls.
 
3) a combo: start 1 actor that receives everything, and then it
creates an actor to actually send every message.
pros: should be as fast as 1 and have no dependencies between message
send success. cons: more complex, maybe can't share session between
actors(?)

Thanks so much for listening to this. Does anyone have any thoughts or
suggestions?

Paul

--
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.


Patrik Nordwall

unread,
Apr 10, 2011, 4:02:00 AM4/10/11
to akka...@googlegroups.com
I would suggest creating an email actor that knows about the technical bits of sending emails. It receives messages containing all information needed for sending 1 email, i.e. recipient, title, body etc. It will be fast to send 200 messages to this email actor, which will then produce emails in its own pace. If you need to send the emails in parallel you can start several email actor instances and use load balancer actor in front of them. Does that make sense?

You can start the email actor in advance. You can use supervisor to restart it if it crash.

/Patrik

On Sun, Apr 10, 2011 at 3:58 AM, Paul Lambert <pa...@paulitex.com> wrote:
--
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.




--

Patrik Nordwall
work: Scalable Solutions
code: http://akka.io
twtr: @patriknw


foolshat

unread,
Apr 11, 2011, 5:17:28 AM4/11/11
to Akka User List
Hi Paul, I've successfully written an email actor with Akka and
RabbitMQ.

In summary it works like this : A client actor class constructs an
object which contains the SINGLE email's details eg from, to, bcc,
message text etc, converts that to JSON using Google GSON library[1]
and puts it on to a a durable Rabbitmq[1]. I chose JSON so any future
client can grab the data from the queue.

Using Akka microkernal to host an actor which is monitoring the
RabbitMQ using AMQP, it deserializes the message and tries to send the
email. If the email can't be sent, or the actor blows up, the message
remains on the queue and will be retried. If you turn everything off,
the durable queue retains a copy of the emails, and the actors will
continue processing the next available message from the queue on
restart.

Multiple emails are sent via sending multiple JSON messages onto the
queue, allowing Akka to spin up more threads all by itself. You can
then have multiple email actors on multiple machines, put the queue on
another machine, so scaling out your app.

There is a bit more involved than I describe, eg multiple queues for
redundancies, retries for the email sending etc.

In the system I'm developing, I'm currently using 7 RabbitMQs queues
and 7 Akka Microkernals, with about 10 actors. So far as the system is
in a live test with 20 users, but will scale up to 10k users. I have
so far, had 0 faults with Akka. The only faults have been my code
bugs, or requirements s misunderstandings/changes.

In my scenario, AKKA really just works. So thanks to Jonas and all the
contributors to Akka !

A plug for Jonas: Jonas is running some AKKA courses in London. I'm
going to the May one.
http://skillsmatter.com/course/java-jee/jonas-boner-akka-scalability-fault-tolerance-concurrency-remoting-actors-stm

[1]http://code.google.com/p/google-gson/
[2]http://www.rabbitmq.com/

Reply all
Reply to author
Forward
0 new messages