Hacker News new | past | comments | ask | show | jobs | submit login

I'm not the parent poster but I'll have a go. Please feel free to correct me if I've got parts wrong, I'm hoping to learn something too.

In other languages, lets say Erlang as an example, actors themselves do not have concurrency concerns. The receive loop/handler just executes everything as though it's single threaded. The code is very easy to reason about. It also applies backpressure in that if your synchronous loop is blocked, your mailbox will fill up.

If you need concurrency, it's done by talking to other actors, which can be processing on another thread under the hood. But the thread part of it is managed and you are not dealing with threads per se, you just know that if you have multiple cores and you send a message to another actor, it can be scheduled to run on another core safely.

If you want to run a bunch of tasks in parallel, you could use a pool of actors up to around the number of cores you have, and the parallelism is at maximum the number of actors in the pool.

Sorry if i'm over explaining, I just wanted to set the stage.

One of the benefits of this arrangement is if something is going slowly you can order the list of actors by biggest mailbox and you can see where your bottleneck is. And if you are using a lot of memory you can just order the actors by the memory usage and you can see where the big state lives.

With akka actors, instead of just dealing with the actors and actor pools, they suggest you make actors non-blocking. The way you do this is with Futures. Suddenly all the simplification of the actor model goes out the window. It mixes an async programming style with an actor model that doesn't need to be async! So you have the negatives of asynchronous programming and very few benefits of the actor model. I realise

How do you identify the bottlenecks of the system? Maybe your execution context is full - actually I'd love to know how people debug their execution contexts in general.

Last I checked, execution contexts would spawn new threads as well, so not only are they heavyweight (compared to erlang processes) but you have the operating system schedule them instead of the thing that knows how to best schedule them which is your language runtime.




Also, serialization and object versioning challenges. I think I mentioned this in another comment but the lack of static typing in erlang/elixir tends to fence your composition model to where these sorts of problems are elided or explicitly handled in code.

But AFA Async, I guess I have thoughts.

> With akka actors, instead of just dealing with the actors and actor pools, they suggest you make actors non-blocking. The way you do this is with Futures.

I don't know how things work in JVM/Akka specifically but on the .NET side the use of async is 'Tolerable'. We have a ReceiveActor that lets you wire up your message type to an async method and it handles all of the stashing/etc internally until the future completes. You have to type a couple extra words but they're the same words you have to type everywhere else you use async.

With the other sugar .NET gives you it's really not too bad. In the system our team built, the main piece of 'blocking' code we have is a call to a C library that does not have any real 'async' bindings. The rest were things like loggers, although typically if 'logging' is blocking either you're logging too much or the rest of the system is probably not in a good state anyway. (edit: FWIW, the 'block' is 80-100ms and constant, we can live with it for our case)

> How do you identify the bottlenecks of the system? Maybe your execution context is full - actually I'd love to know how people debug their execution contexts in general.

Interestingly, Akka.NET doesn't quite have this sort of problem.The default Dispatcher (At least that's what we call the base type) runs on the .NET Thread pool which has a good degree of 'self tuning', and you can peek at the number of threads vs what the pool maxes out at with 4 lines of code or so. However in .NET we have 'SynchronizationContexts' which result in the need for special dispatchers for things like a UI update (as most UI frameworks have their own context for handling UI).

> One of the benefits of this arrangement is if something is going slowly you can order the list of actors by biggest mailbox and you can see where your bottleneck is.

You could probably hack together something off of akka visualmailbox [0] as it shows how to grab metrics from 'inside' a mailbox. I did a toy port to .NET and while on that side I had to do a lot of 'configuration' and still need to create metrics collecting mailboxes for all the types (we don't have traits...) but it seemed to actually work not-bad.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact