Hacker News new | ask | show | jobs
by bostonsre 1690 days ago
Has anyone had great success with akka? It seems like it could definitely solve some problems elegantly. My team has had trouble with maintainability due to complexity (not clear if that's inherent in akka or just with how we implemented it). It can be somewhat managed by senior engineers but has seemed to be difficult for junior engineers to effectively maintain akka code.
7 comments

I've now worked for about six months on a Akka.NET codebase. I find it a very elegant high-performance framework that gives you a lot of flexibility in how you want to solve a wide range problems.

This being said, I've been burned already several times by the complexity and its raw power. The codebase tends to become verbose and difficult to navigate (everything being an ActorRef). Debugging is difficult and coding is challenging for junior engineers, as you said. I found it very unforgiving to mistakes, and it's easy to shoot yourself in the foot if you use the abstractions without knowing very well what's going on under the hood. Edge cases can be very tricky to manage.

I'm still very conflicted about it. One one side the services powered by Akka are quite stable and performant, but I'm not sure the complexity justifies the means.

Please take a look on Proto.Actor (C# version). Very elegant and lightweight solution.
The version for go is awesome.
Doesn't .NET now have a very similar core library anyway?
Only thing I can think of is the Task Parallel Library but I’m not sure how that compares to Actors.
Not at all, what I know. well it runs stuff in parallel but i believe thats where the similarities end.
That jogged my memory; what I was thinking of was TPL Dataflow. https://docs.microsoft.com/en-us/dotnet/standard/parallel-pr...

> The Task Parallel Library (TPL) provides dataflow components to help increase the robustness of concurrency-enabled applications. These dataflow components are collectively referred to as the TPL Dataflow Library. This dataflow model promotes actor-based programming by providing in-process message passing for coarse-grained dataflow and pipelining tasks. The dataflow components build on the types and scheduling infrastructure of the TPL and integrate with the C#, Visual Basic, and F# language support for asynchronous programming.

I stand corrected! Thank you!
You might be thinking of Orleans, but it's not exactly core.
We use Orleans on my team and it has been 99% worth it. The 1% is mostly problems due to bad configuration, easily remedied.
I'm glad to hear that somebody's using it in the wild. It was rejected at my place of work in favour of a BPMN-driven process engine. The thinking was that it's too difficult otherwise for business-people to understand the process.

Does your company write about its experiences?

Besides Orleans there is also the Service Fabric SDK and now also Dapr
Also https://getakka.net/ , but haven't used it myself
I've had good success with akka at multiple companies. At Protenus the core ETL is based on akka streams. Which has worked great. No notable issues. Tho we don't run in clustered mode.

At glngn we didn't use akka streams (outside of akka http) but did use event sourced, persistent entities powered by akka typed in clustered mode. Deployed to k8s. Which definitely took effort to set up nicely and enable smooth deployments. Our clusters were not huge so many problems did not show up (split brain).

I haven't used other systems that provided an equivalent to akka typed persistent entities. I can't compare akka in that sense. However the event sourced persistent entities model is really, really effective. Definitely a different paradigm: some stuff is trivial that would otherwise be a trial.

I suspect many of the benefits could be achieved by using something like Kafka feeding non clustered nodes. But never tried.

I used to work on the Akka Team, mostly on streams, but I was doing different stuff elsewhere in the last years, not touching Akka much. To be honest, I am quite emotionally distanced nowadays from Akka...

That said, it still feels good reading success stories from people who used it. Thanks, you made my day!

You're welcome! I think akka has been making great strides in polishing the rough edges. (Along with the rest of the Scala ecosystem TBH). Unfortunately that doesn't seem to generate the hype I'd argue akka deserves shrug
My team had migrated about 35 codebases from a mix of Play, Scalatra, Ruby, and Python, to Akka HTTP. The unification definitely made it easier for juniors to start work on unfamiliar codebases, but the same could be said if we unified on something else. That being said, a portion of the services did make use of Akka streams & actors and we’ve found a lot of success there that otherwise would’ve been complex code with locks or synchronized blocks. Stuff that I’d rather not have to onboard engineers with or review their PRs and miss an unlock(). It’s probably a steeper learning curve by teaching them about actors and futures, but it means they’ll be writing safer code by design, and reviewing their PRs becomes easier for me.

Just make sure the actors are small and have one focus. When they get too large and do too much is when they become unwieldy and difficult to maintain.

In the past I have designed, implemented and brought into production many Akka based systems with medior and senior teams. Most of these were akka-streams based.

The Akka actor model requires a different mode of thinking which can cause problems for experienced engineers. Ideas such as 'let it crash' and at-most-once-delivery are not trivial. Basically systems design based on resilience instead of robustness.

When Actor based systems are well designed, they can be extremely powerful, scalable, resilient and adaptable.

Small nitpick. I found that akka-streams missed many useful primitives. For our toolkit, I designed flows with retry-logic, flows with cache lines and flows with metric measurements (sending data to Datadog).

I found that akka (akka-core) was not just bad, but bad enough that it dragged down the reputation of Scala. Most (maybe all) of the time simple future-based code accomplishes the same thing in a much clearer way, and without sacrificing the type safety that's one of the biggest strengths of Scala.

(Some higher-level things under the akka umbrella e.g. akka-http (formerly spray-http) and akka-streams might be useful; not coincidentally they also tend to be more type-safe)

i’ve seen at least two cloud services using akka for a component that required long-lived stateful connection management. while i think both ended up being successful because of akka, it required retrofitting a lot of libraries that already existed to fit the actor paradigm, as well as requiring at least one person who really understood akka.

id also say some decisions around akka monitoring and how that has related to lightbends monetization makes it more difficult than it should be to build observability around the internals of akka, ex. emitting metrics on actor queue depth.

No. In fact the Play Framework 1.x (before it went to Akka) was simple perfection. Like Ruby on Rails but with so many improvements. Super simple but fast, performant and not really lacking anything a web framework needs (coordinating background periodic jobs between servers required setting a config file but it wasn't a big deal).

In play framework 1 a new API method could be the following

>@Check("administrator") // Authentication scopes allowed for this method

>public static String returnHeading(int id) {

> return createQuery("select heading from Article where id=%", id).getResult();

>}

See how little boilerplate i have? A junior dev can work with this without shooting their own foot. I used to have clients come into the office and ask for a new API method and I'd type out the API in Play Framework 1.x, type the tests (the framework had a great foundation for unit and integration tests) check that the SQL was sane and deploy in half a day. There's nothing more i want. It scaled well horizontally too. You just had haproxy/nginx in front of multiple servers.

Now you might say "But what if you had a web request that took days and needed all cores on all servers to communicate with each other as they concurrently worked on this mammoth task" to which I'd say shut the fuck up.

Play Framework 2.x is when the Play framework adopted Akka. I'm going to be mean and takes Lightbends hello world using Akka as a taste for those unaware of what this beast is: https://youtu.be/rIFqJxMJ1MM?t=428

I'm just going to copy paste some stuff from the Akka wiki to rub it in.

Akka supports multiple programming models for concurrency, but it emphasizes actor-based concurrency and the eventsourced library provides event-driven architecture (see also domain-driven design) support for Akka actors. Akka has a modular structure, with a core module providing actors. Other modules are available to add features such as network distribution of actors, cluster support, Command and Event Sourcing, integration with various third-party systems (e.g. Apache Camel, ZeroMQ), and even support for other concurrency models such as Futures and Agents blah blah blah blah blah.

Sorry I'm being rude but surely even the people making Akka can see the issues? There might be a use case for Akka. But a webserver for a startup is not a use case. Play Framework was built as a web framework and Play Framework 2.x seemed to focus in on a limitation that practically no one would encounter and make everything about that one use case. Play Framework 2.x overcomplicated the entire stack and gave no benefit. There's a reason Play Framework 1.x is being maintained and patched still. The complication from 2.x and Akka is not worth it at all.

Not familiar with Akka of Play2, but you articulated the point of overcomplicating the task of returning a simple response to a simple request via a litany of rarely useful concepts quite clearly.

OTOH, I wish popular web frameworks had a clearly documented 'no magic' option that doesn't critically depend on global methods and decorators. Again, not familiar with Play1 other than your example, but I recently did spent too much time wrangling a moderate backend build on with python/flask as a beginner going through the learning curve. After the first 5 minutes of 'look ma, I have a running server', the overreliance of globals became an unpleasant annoyance impeding test writing, with surprises abounding.

Yeah, I agree, despite being an advanced Python programmer and a fan of the language. Writing a production grade web app requires some proprietary boilerplate black magic that is quite difficult to get right at first, but once you get it right, it’s something you carry along with you across projects.

Declaring, managing, and providing a proper test fixture for the ‘app context’ in a Flask app can be rather hideous. Having said that, despite the poor aesthetics and contours, that black magic is incredibly reliable once you get it right.