Example of integration Akka with existing java project

ses picture ses · May 16, 2013 · Viewed 12.6k times · Source

If I already have existing java web application that uses spring and servlet container. What is the proper way to integrate Akka in it?

Like I'g going to have Actor1 and Actor2 that communicate with each other. What would be the entry point to start using those actors? (like: 1. put it there 2. change config 3. get reference to actor)

I found http://doc.akka.io/docs/akka/2.2-M3/general/configuration.html But his does not provide me a glue. Just want to get real example of integration.

Is there some simple integration example?

EDIT: Application does some search, getting some data from outside, storing info to files.

The application is quite big. Some components/object can leave their own life, that is out of direct client requests, it can do some things is parallel. Like some singleton objects that has mutable state in it.

The thing is I do not know exactly where I can apply Actors, I'm investigation it. But what I have already is lots of synchronized blocks here and there.

And, it is already, I believe, kind of sign that the actors might be applied. (because I'm not sure, maybe I forgot to put some synchronized, and of course there are no integration tests for it)

About configuration, I'm just not sure should I configure some application.conf for let Actrors/Akka live there (since documentation itself describes it).

What I see:

@Component("someManager")
public class SomeManager {
 List<Some> something;  // mutable state, that why I use locks here.
 // methods: add(), delete(), update()  
}

I could make it SomeManagerActor

SomeManager is used from controller. Thus, it would be nice to have controller Actor as well ? I it want to receive feedback into (onReceive() method).

This is kind of disputable... That's one more reason why I need some example.

I believe I can improve application by getting rid of all synchronized/whait/notify stuff, moving responsibilities to actors, using messages as a way of communication with/between them.

Or like this it could be the actor to write to property files:

EDIT:

For example, for now what I found: To make Actor1 send message to Actor2 I use a trick:

// somewhere in existing code
public void initActors() {

        ActorSystem system = ActorSystem.create(example");

        // initializing
        final ActorRef actor1 = system.actorOf(Props.create(Actor1.class), "actor1");

}

Actor1 has a method preStart() that is started as soon as I get reference to it (above). And it sends message to Actor2:

@Override
public void preStart() {

But I'm not sure that it is good why to initialize two actors to do their work.

Answer

ses picture ses · May 21, 2013

Answering my question. Just to share my thoughts, what I came up with.

If we already have existing working Web application based on Servlets/Spring MVC, it seems that often there is no good reason switching to Actors/AKKA (or introducing actors to the existing system just for hack of it) if in our application we:

  • Don't have: Thread workers logic when tasks are splitting over the background. (usually, the typical web application doesn't have this), like long long calculations. (parallelism).
  • Have: If we have sequential calls - when one component calls another one, then that calls another one, where the calls are depended on each other: Like Controllers call Component, Component save some data to some List (which is mutable, but synchronized as Synchronized-list ).
  • Do not have free time to replace all Spring Controllers by Akka actors or using different servers at all (not Tomcat) (there are not so many managers/product owners who would allow you to do that)

What is wrong having Actors in this simple system:

  • Having tons of messages (classes that wrap commands to/from actors) that come through the components instead of calling general methods (using advantages of OPP, implementing interfaces, having several implementations - but Actors usually final class).

  • Having messages as a string, not a good solution either - since it's hard to debug.

  • In such a system (like MVC site), usually, there are no so many things to synchronize (it is already quite stateless). There are 0..2 mutable shared data in each Controller/Component. Which is not so hard to synchronize (just make a habit to put synchronize everything common and shared at the top of your classes (so that states are recognizable/localized). Sometimes you just need to synchronized collection or use java Atomic wrapper type.

When the Actors might be used though for an existing application. Use cases are might be like this:

  • when we have long-lived search, that goes through several sources (kind of thread worker). Having several/pull of MasterActor -> SiteSearchActor (like it was described for computation PI here). The MasterActor has the final result. Where SiteSearchActor calculates (do search over several sites) for several clients.
  • or when we have any thread forks, out of current servlet ones
  • when we know for sure / figured out that our system will be used by millions of clients (even with simple logic), we should think in advance about scalability and performance (
    • actors scale good - we can delegate one work from one actor to N-ones.
    • actors safes processor type when working with threads (no need 10000 threads for 10000 clients, in most cases enough have 4 threads (the same amount as processors core let's say) )

But in general, I agree with this article about concurrency and parallelism. If I have chance to make an application from scratch, I would use Akka without Servlets container and caring somehow about messages (command classes) and OOP when it needs to be used (there are not so many OOP in general web-applications. I should say anyway. But nobody prevent keep some business logic in OOP way, actors just a communication glue). That is much better/simpler than using JMS for example.

But like I said:

Actors / Akka is good for:

  1. Services/Controllers (instead of Servlet/SpringMVC ones)
  2. Thread workers like logic
  3. Especially for a project from scratch (when current infrastructure does not make you barriers applying actor one).

The only question I have now is performance comparison. Assuming we know that:

having 10000 threads in one JVM with synchronized and locks for shared mutable data in our MVC Controllers/Services are might be very bad from the performance perspective. Since there are many possible locks, threads that are concurrent (a rival or competitor for a hared resource) to each other.

If we have the same scenario for AKKA/Servlets with N (actors, where N much more less than 1000), we most likely would have much better performance (since nobody blocks anyone, except the queue itself, no need to switch from one thread to another).

But even if having a system with 10000 clients for Servlet based (thread model) application, with 100 clients it might work very well. And If we have a pool of connection (certainly we have) it does the same work as Actor's queue (inbox), scheduling clients to have access to some piece of service. It could improve our performance in K times (where K is much more that if we didn't have a pool - letting thread block each other desperately).

The question is:

Is it a good reason to not apply AKKA for existing servlet based application?

Taking this is an argument: Even having an old system on Servers, with connection pool may improve the performance to a good level. And this level, most likely, might be good enough in order NOT to apply AKKA to existing Servlet application, like trying to change servlet model (that' supposed to be bad comparing to Controllers on top of AKKA).

Does it make sense to think like this?

Consider connection pull is kind of INBOX (like in AKKA) scheduling the commands (connection).

Even if Servlets model is bad (having a deal with locks in the rest(active) thread that is creating by connection coming from connection pool).

It might be good enough with the connection pool, which is forgotten when comparing Akka to servlets based stuff. We still can tune our application, changing MAX-CONNECTION in the connection pool. And usually, we do all our best to make application stateless, so, in most cases, we do not synchronize anything.

But of course, it is bad having only One connection pool for Whole application. If comparing to Actors each actor has each own connection pool (mailbox), and each actor might be responsible for accepting HTTP requests. That model certainly better.

P.S. In most cases, Futures are good enough. Actors are good if you want "safety" to store the state in it (that differs it from the Future basically).

UPDATE: Some people believe that it is a bad idea at all to use Actors. What is good is - pure functional approach or something that scalaz already provides (as well as Haskell I guess) - but not for remote calls yet.