9 comments

  • phtrivier3 hours ago
    &gt; State can be persisted (e.g., to storage, database or event log) between messages. If an actor crashes, it can recover its state on another node and resume processing.<p>And that&#x27;s the part I never managed to solve, personally. The state of actors tend to look &quot;a lot like&quot; your domain objects, but you don&#x27;t want to store it until the very end.<p>Do you have a data-model for each actor to store their own snapshots ? When do you snapshot ? When do you sync with the &quot;ground truth&quot; ? Do you have different tech for each kind of state (eg &quot;term storage&quot; for actors, then relational db for ground truth ?)
    • withinboredom33 minutes ago
      &gt; When do you snapshot ?<p>In Durable PHP (an actor system for PHP), it tries to achieve at-most-once processing guarantee (though more often than not, it is exactly-once).<p>1. commit the current state<p>2. send outgoing messages<p>3. ack the original event<p>If we fail before 1, we simply retry<p>If we fail between 1-3, we simply rewind and retry
    • dkersten1 hour ago
      This is what I’ve struggled with when trying to learn erlang&#x2F;elixir&#x2F;gleam:<p>If I go all in, then modelling as actors makes sense. The domain model is modelled as in-memory actors, using erlang features for persistence and what not.<p>But most of the time this isn’t what we want in modern software: instead our state is in a database and we are executing in a request-response setup. This seems to be mismatched with actors, as, it seems to me, at least, you’re mapping the database states into your actors on each request and then back on response, at which point, what do actors actually buy you?<p>The same mismatch exists with OO too, of course, but with actors there are a bunch of benefits that you get by going all in, which it seems to me are lost if you’re simply building a database backed request-response system.<p>I mean, many of the OP’s pros of actors rely on actors being long lived things, rather than short lived within a request.<p>Maybe I’m just missing something. But maybe it’s also just not suited to typical web api backend?
  • karmakaze11 hours ago
    I suspect that a lot of what can be done with actors can be done in Go using the &quot;Don&#x27;t communicate by sharing memory, share memory by communicating&quot;. Basically a consumer of a channel can act like an actor. What we don&#x27;t get for free is the activation and resiliency. A closer one would be Erlang&#x2F;Elixir on the BEAM. On the more advanced end would be using F# or Pony.<p>Curious to see what the follow-up parts will post. I am interested in actor model programming and want to see different ways of understanding and using them.
    • jerf1 hour ago
      I view actors like I view &quot;object orientation&quot; in general. In fact they&#x27;re not even all that dissimilar, being respectively &quot;store and manipulate state attached to a single runtime context&quot; (be it &quot;thread&quot; or &quot;green thread&quot; or async context or whatever) and &quot;store and manipulate state attached to a single highly-structured value&quot;. (They go together pretty well, actually.) The primary value comes from the idea, and it can and should be managed and manipulated for the local context.<p>Many people will come along and insist that you need every last thing according to some particular definition (e.g., in OO, &quot;you need multiple inheritance and all of public, private, and protected, and you need virtual methods and you need and you need and you need OR YOU DON&#x27;T HAVE TRUE OBJECT ORIENTATION AND EVERYTHING WILL FALL APART&quot;), and will insist that everything at every layer of your program will need to be structured in this paradigm OR YOU DON&#x27;T HAVE TRUE WHATEVER AND EVERYTHING WILL FALL APART, but both claims are observably false.<p>I use actors in nearly every program I write, in almost any language I write in anymore if there&#x27;s any concurrency at all. But they are a <i>wonderful</i> tool to drop in somewhere, and encapsulate some particularly tricky bit of concurrent logic, like an in-memory concurrent cache, without having to restructure everything to be All Actors All The Time. I spent a lot of years in Erlang and still sort of consider this a mistake, up there with Java trying to &quot;force&quot; everything into OO by forcing everything to be in a class, even if it has no business being there. You don&#x27;t need to go down someone&#x27;s check list and dot every i and cross every t &quot;or you don&#x27;t have <i>true</i> actors&quot;. It&#x27;s very much an 90&#x2F;10 situation where the vast bulk of the benefit is obtained as soon as you have anything even actor-ish, and the additional marginal benefit of going all the way down to some very precise definition can be marginal and may even be negative if it requires you to contort your code in some unnatural way just to fit into some framework that isn&#x27;t benefiting you on this particular task (e.g., Erlang has a lot of nice tools but if you&#x27;re building a purely-local command-line app with it for whatever reason you probably don&#x27;t have a great need for clustering support or OTP in general).
    • suraci7 hours ago
      &gt; a lot of what can be done with actors can be done in Go using the &quot;Don&#x27;t communicate by sharing memory, share memory by communicating&quot;<p>Yes, it is logically correct since CSP and Actors are solutions for the same problem(concurrency)<p>And I do think CSP is easier to use compare with Actors as a programming model, but when it comes to distributed and business applications, the comparative advantage is reversed
    • asplake6 hours ago
      Why F# there?
      • karmakaze1 hour ago
        I was thinking of Mailbox Processor and available Actor libraries. Here&#x27;s a pretty good rundown I found for some[0]:<p>&gt; Actor Model in .NET<p>&gt; In the .NET world, there are at least a few battle-tested frameworks that allow you to build stateful systems using the actor model. The famous ones are Akka.NET[1], Orleans[2], Proto.Actor[3], and Dapr[4]. All of these systems support distributed mode, as well as a bunch of other features like actor supervision, virtual actor, parent-child hierarchies, reentrancy, distributed transactions, dead letter queue, routers, streams, etc. In addition to these frameworks, .NET has several lightweight libs that do not have many of the listed features but still allow the use of the actor model. For example, F# has built-in support via Mailbox Processor[5] and also there the toolkits: TPL Dataflow[6] and Channel[7]. TPL Dataflow and Channel are not actor model implementations but rather foundations for writing concurrent programs with the ability to use the actor model design pattern.<p>[0] <a href="https:&#x2F;&#x2F;medium.com&#x2F;draftkings-engineering&#x2F;entering-actor-model-nirvana-with-f-and-tpl-dataflow-b8ab34b84656" rel="nofollow">https:&#x2F;&#x2F;medium.com&#x2F;draftkings-engineering&#x2F;entering-actor-mod...</a><p>[1] <a href="https:&#x2F;&#x2F;getakka.net&#x2F;" rel="nofollow">https:&#x2F;&#x2F;getakka.net&#x2F;</a><p>[2] <a href="https:&#x2F;&#x2F;dotnet.github.io&#x2F;orleans&#x2F;index.html" rel="nofollow">https:&#x2F;&#x2F;dotnet.github.io&#x2F;orleans&#x2F;index.html</a><p>[3] <a href="https:&#x2F;&#x2F;proto.actor&#x2F;" rel="nofollow">https:&#x2F;&#x2F;proto.actor&#x2F;</a><p>[4] <a href="https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;dotnet&#x2F;architecture&#x2F;dapr-for-net-developers&#x2F;actors" rel="nofollow">https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;dotnet&#x2F;architecture&#x2F;dapr-fo...</a><p>[5] <a href="https:&#x2F;&#x2F;www.codemag.com&#x2F;Article&#x2F;1707051&#x2F;Writing-Concurrent-Programs-Using-F" rel="nofollow">https:&#x2F;&#x2F;www.codemag.com&#x2F;Article&#x2F;1707051&#x2F;Writing-Concurrent-P...</a><p>[6] <a href="https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;dotnet&#x2F;standard&#x2F;parallel-programming&#x2F;dataflow-task-parallel-library" rel="nofollow">https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;dotnet&#x2F;standard&#x2F;parallel-pr...</a><p>[7] <a href="https:&#x2F;&#x2F;devblogs.microsoft.com&#x2F;dotnet&#x2F;an-introduction-to-system-threading-channels&#x2F;" rel="nofollow">https:&#x2F;&#x2F;devblogs.microsoft.com&#x2F;dotnet&#x2F;an-introduction-to-sys...</a>
  • LaserToy10 hours ago
    I love actors as a concept and I heard some large companies (Expedia) implemented large parts using them.<p>But I also saw how hard it is to understand a large system that built using actors. It is just hard to comprehend all the communication pathways and what happens in the system.
    • jghn17 minutes ago
      &gt; It is just hard to comprehend all the communication pathways and what happens in the system.<p>Having worked on large scale actor-based systems before, I&#x27;ll attest this is quite true. However, what often gets lost in these conversations is that this is also true of large scale OOP based systems as well.<p>If one takes a few steps back and squints, there&#x27;s really not much difference between Objects and Actors: in both cases you have a namespaced entity (object, actor) that receives signals via some defined mechanism (methods, messages) which lead it to perform some action.
    • jspdown3 hours ago
      When the design closely aligns with the real world problem it solves, communication pathways are natural and you don&#x27;t really have to care much about them. What matters is the Actor&#x27;s role and making sure it represent a strong domain concept. The rest follows naturally.<p>But to be fair, it&#x27;s never that simple and you always end up with some part of a system that&#x27;s less &quot;well-designed&quot;. In that case,figuring out who talks to who can quickly become a nightmare.<p>Actors are great on the paper, but to benefit from them, you need great understanding of your domain. I tend to use it later in the development process, on specific part where the domain is rich and understood.
  • jatins5 hours ago
    is this AI generated? I flagged because seemed very low on substance and just generic bullet points
    • jeremycarter4 hours ago
      It&#x27;s just part 1. I have just published part 2 which goes into more detail.
  • yodon14 hours ago
    Huge fan of building systems on top of Orleans Actors (one of the tools discussed in the article)
  • dirtbag__dad14 hours ago
    Does anyone care to share an example of the OrderService that is not anemic?
    • zamalek9 hours ago
      Some actor frameworks (Erlang, Orleans) would interpret each order being an actor instance, and each order line being an actor instance. To make that clearer: each order row would _logically_ have an actor running somewhere in your cluster. This would mean that an order actor would, by nature, have a &quot;add order line&quot; receiver (i.e. method). Each is in charge of how its data is stored. In reality, you&#x27;d _probably_ only do this stuff on the command end: query would hit tables+joins+whatever directly.<p>If you work this back to DDD, then the Order entity would have an AddOrderLine method. The central service would be responsible for handing out Order entities and saving them once modified.<p>Up until a few years ago (prior to my previous job) I was a hypothetical believer in DDD and actors as two equally viable alternatives. I am now <i>strongly</i> against DDD, but still agree with the article on a hypothetical basis about actors.
      • svieira9 hours ago
        What did you learn about (by using?) DDD that made you decide strongly against it?
        • zamalek26 minutes ago
          DDD advocates for creating a shared lingo across everyone involved, including customers if they are highly embedded in the design process. This I agree with.<p>Ultimately DDD attempts to create real-world analogies in code; you know, dog inherits from pet inherits from mammal etc. In my opinion, this approach to OOP easily ends up creating code that is difficult to reason about. Probably because real-world things often have many responsibilities. Code becomes especially confusing when you have dozens of methods on domain objects that interact across several domains: the system-wide control flow becomes extremely complex. Now add outlier code&#x2F;hacks, likely written to meet an unrealistic deadlines, and things rapidly become completely incomprehensible.<p>And there&#x27;s more that&#x27;s hard to put to words. I code for the love of it, and I truly hated every moment working in DDD code. That was I completely novel experience for me: I&#x27;m fine with boring work (it has to happen), but DDD just hit very differently.
      • jeremycarter4 hours ago
        I agree. I&#x27;m not advocating doing a purist DDD solution but rather using similar modelling techniques and just making naive actors.
    • jeremycarter13 hours ago
      It&#x27;s tricky to provide a really good example right now. I notice in the .NET world there are like these DDD &quot;starter packs&quot;, and my god, they&#x27;re just layers of maintainability hell. If you look at older OOP&#x2F;DDD books you&#x27;ll notice that the domain object has real world methods on it, just like as if it were from a UML diagram.<p>What you should end up with are plain OOPy objects that mirror the real world. They&#x27;re not skewed or constrained by their database model. They shouldn&#x27;t have any dependencies on your infrastructure layer. The object should encapsulate state, behaviour, validity and consistency.<p>An example (which is probably overkill) would be <a href="https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;dotnet&#x2F;architecture&#x2F;microservices&#x2F;microservice-ddd-cqrs-patterns&#x2F;net-core-microservice-domain-model#implement-domain-entities-as-poco-classes" rel="nofollow">https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;dotnet&#x2F;architecture&#x2F;micros...</a><p>The next post is about modelling an actor and it might provide more insight for you.
      • ibgeek13 hours ago
        It&#x27;s not clear from the article whether actors offer significant benefits (or disadvantages) for data modeling versus the traditional OO paradigm. The article reads more like an introduction that describes the problem and teases a solution rather a complete article that offers a solution and evaluation of it.
        • jeremycarter13 hours ago
          That&#x27;s fair feedback. I wanted to post it in 3 parts, but I see now I probably should have just made one large post.
          • macintux11 hours ago
            You could always post the 3 parts simultaneously, so anyone who wants to dig deeper can continue into the series.
  • dboreham10 hours ago
    Some background: <a href="https:&#x2F;&#x2F;en.m.wikipedia.org&#x2F;wiki&#x2F;Communicating_sequential_processes" rel="nofollow">https:&#x2F;&#x2F;en.m.wikipedia.org&#x2F;wiki&#x2F;Communicating_sequential_pro...</a>
    • gpderetta5 hours ago
      Better link: <a href="https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Actor_model" rel="nofollow">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Actor_model</a><p>CSP is a bit different from the actor model (see the comparison section in the page you linked).<p>The biggest difference is that CSP communication is synchronous.
  • ibgeek13 hours ago
    The article seems to be smashing together two (seemingly) unrelated topics and doesn&#x27;t offer much in the way of a solution. What alternative design does the author propose? Is it possible to solve the problem with traditional object-oriented design techniques? It&#x27;s not clear that the issues presented require or substantially benefit from the actor model without seeing a best in-class OO example.
    • jeremycarter13 hours ago
      As I mentioned there&#x27;s nothing novel in this post, especially for a senior. This is more about getting some context out of the way so that I can show some techniques in a future post.
  • kiitos9 hours ago
    <p><pre><code> Isolation: Since actors process messages they receive sequentially, there are no concurrency issues within an actor. This simplifies reasoning about state mutation and transitions. ... Fault Tolerance: State can be persisted (e.g., to storage, database or event log) between messages. If an actor crashes, it can recover its state on another node and resume processing. </code></pre> The system model in which each actor instance is single-threaded, processes received requests individually and sequentially, and can &quot;crash&quot; in a way that affects only the in-flight request, is a total anachronism, irrelevant since more than a decade, at any meaningful scale.
    • packetlost9 hours ago
      I don&#x27;t see how this isn&#x27;t still both possible and entirely relevant to modern systems. An actor is not necessarily a system process&#x2F;thread. It has more to do with scope&#x2F;context than any particular execution model. Think more like a request handling context in an async language.
      • kiitos8 hours ago
        It&#x27;s true that an actor is not necessarily a system process. It can be a process, or a thread, or a coroutine, or etc. But &quot;crashing&quot; isn&#x27;t anywhere near so ambiguous. Crashing doesn&#x27;t mean the request fails, or the thread gets killed -- crashing means the underlying process terminates.<p>That may not be how <i>some folks</i> understand the concept of crashing, but it&#x27;s definitely how <i>most folks</i> understand it, at least insofar as they write software.<p>1 service instance needs to be able to handle O(1k+) concurrent requests at scale, and a failure in any given request can&#x27;t impact other in-flight requests. Those failures aren&#x27;t crashes, and that software isn&#x27;t crash-only -- using those terms just obfuscates things, and makes everything harder for everyone.
        • jerf1 hour ago
          Any time you are communicating between multiple programming language communities, it is important to understand that they <i>will</i> have differing definitions for things, to extend grace to people trying to communicate across those barriers, and to not apply dogmatic definitions of terms that apply to the contexts you happen to be familiar with but are used differently elsewhere.<p>&quot;Crash&quot; is not a universally defined term and you will find there are plenty of communities that do not agree that &quot;crash == OS process terminating&quot;.
    • t-writescode9 hours ago
      It sounds like you may know a lot about this; but each actor operating in a &quot;single-threaded&quot;, &quot;do one thing at a time on your own&quot; paradigm is what I&#x27;m familiar with, especially with Akka.NET, where my experience lies.<p>Please tell me more about its irrelevance, etc, I&#x27;d love to learn!