0

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

pacman
  • 797
  • 10
  • 28
  • Wild guess: thread is a limited system resource, actor waiting for async reply from e.g. DB is not (thread will be freed for another actor). So if your application is asynchronous you can keep open a way more connections than with 1 thread = 1 connection model (like Tomcat) and it will not bring your system down. – Victor Moroz Aug 03 '16 at 23:12
  • I don't think it's about "who's better". The actor approach doesn't require a thread per actor, thus allowing you to *scale* as the number of requests increases, as opposed to a dedicated thread per request where the amount of threads is tightly coupled to the underlying OS. If your service isn't going to be stressing your machine, I doubt you'll see any major difference. – Yuval Itzchakov Aug 04 '16 at 06:53
  • Basically, you are limited to the thread count, which is limited system resource, on thread per request. It is a problem when most of your threads are waiting for IO and very few of them actually serving users. On the other hand, actors can wait without blocking your threads so that you can serve to more users with the same number of threats. – Mustafa Simav Aug 04 '16 at 08:22

1 Answers1

1

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.

Community
  • 1
  • 1
sascha10000
  • 1,245
  • 1
  • 10
  • 22
  • Additionally I don't know how Threads are used in Tomcat, wich is also an very important question. But I would think of a ThreadPool because it's less expsensive. – sascha10000 Aug 03 '16 at 22:36
  • I wouldn't say this qualifies as an answer to the question. I'd post this as a *comment*. – Yuval Itzchakov Aug 04 '16 at 06:55
  • Please argue why Actors is good for stateless protocols like HTTP? – pacman Aug 04 '16 at 10:31
  • Okay, thanks for the corrections. I will try to outline and reason my answer. First I wanted only to comment it, but then I thought it was quite a good answer especially the link (it's an solved StackOverflow question). – sascha10000 Aug 04 '16 at 13:51
  • I'm not sure if this answers the question. Actors are meant to manage and encapsulate state. I think stateless protocol, in regards to HTTP, is referring to a different context than the state within an application. – Antonio de Perio Mar 24 '18 at 07:07
  • As far as Iam concerned I was talking about the lower levels in the layers when refering to HTTP because Spray does not care about the top "Application Layer". So my point is still valid. But you're right that Iam not answering the question, because I didn't elaborate on Tomcat and threads. But I tried to provide the Information about Spray because at that point in time I was using it in multiple projects and had done some research. – sascha10000 Mar 26 '18 at 12:29