Search code examples
performancescalaakkaspray

Why Actor per request in Spray is better/worse than Thread per request (like in Tomcat)?


Why actor per request in Spray is better or worse than thread per request (like in Tomcat). What strategy provide better performance?


Solution

  • If you take HTTP you have a stateless protocol. Thus it's a perfect fit for Actors.

    I think before writing down each aspect. I redirect you to this good answer which is taking my statement to a more general level. How does Actors work compared to threads?

    EDIT:

    Actors basically don't share state and the data in the messages are immutable. If you are using Threads you may easily exchange Data between them and also need to handle things like lifetime and amount of Threads started. It's a basic fact that shared state (if not immutable) may cause DeadLocks and other concurrent Situations. I won't leave out the fact that you can use preimplemented ThreadPools which will handle many things for you including the ExecutionContext. Many people are using Threads wrong including myself - Iam not a pro in the Topic of Threads and all the problems of concurrency. https://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html

    An Actor should be small an do "one" thing/topic/use-case very good. They're built in an hirachircal manner, which means you have an ActorSystem, an RootActor which can have many childs of different Types and so on. It's communication via sending Asynchronous-Messages (you can also work in an blocking Style). If you start one Actor it is running in one Thread. That means if you send 10 messages which would need to be processed 1 second, all messages will be handled after ~10 seconds. This is not very concurrent and therefore you can spawn more Actors but now if you are using them correct, they run in an amount x of shared Threads. This prevents the Threads from being killed and spawning new ones. It's all handled under the hood and you can configure it via TypesafeConfig. As an unrealistic exmaple you may spawn 20 Actors but they are running in 4 Threads -- not 20. All this stuff is handled by akka-actors and you only need to think about which Dispatcher, Router, Mailbox you are using for your purpose. And thats what spray does.

    Back to HTTP: It's stateless which means, after the TCP-Con is established, you send your HTTP-Request and you'll get your HTTP Response. After that this conversation is obsolete and non-relevant for HTTP. A session will be identified via HTTP-Headers but the protocol itself won't do anything with that, the session stuff is the job of your application. So for handling requests-repsonse spray will have a pool of Threads with a few Actors and they will handle the request and redirect it to your Routes.

    One thing you should have on your radar: Spray is a REST/HTTP Framework. REST implies that each Message should contain all information needed to respond accordingly if you are seeing it very strict and straight-forward.

    I hope this will clear things a little bit up. If you want to dive deeper into the ActorModel used by spray you should look on their site (sorry I have no link for that) or browse the Code which can help a lot. I know it's very basic what Iam telling but there are quite good blog entries on all of those topics and I think this is not the right context to write an entire novel.