[HN Gopher] Actor system for the JVM developed by Electronic Arts ___________________________________________________________________ Actor system for the JVM developed by Electronic Arts Author : dmux Score : 179 points Date : 2022-04-28 14:21 UTC (8 hours ago) (HTM) web link (www.orbit.cloud) (TXT) w3m dump (www.orbit.cloud) | JoeHegarty wrote: | So, I'm the original lead developer of this project. | | This was meant to be a followup to the original version of Orbit | which now lives on as orbit-legacy on GitHub. | | Unfortunately other priorities have meant this project hasn't | proceeded in the past couple of years. I wouldn't really | recommend anyone use either of them. | | However, the ideas and implementation both for Orbit Legacy and | the early version of Orbit 2 contain some ideas and concepts that | may be useful to folks. | | I still think there is immense value in virtual actors (Orleans | from Microsoft is one great alternative for .NET, and Dapr also | looks interesting) but I can't say if we'll ever get back to it. | foob20220428 wrote: | _> "It is heavily inspired by the Microsoft Orleans project."_ | | It's always better to focus on delivering the game rather than | trying to make an own engine... | JoeHegarty wrote: | While in general I agree with that philosophy, it doesn't | really apply in this case. | | When Orbit 1 was initially developed, Orleans was not open | source, so the initial implementation was based off the | Microsoft Research Whitepaper. | | In our specific case, we had a lot of existing experience and | services built on the JVM so adopting DotNet for Orleans | (even if it had been available at the time) was not an | option. The relative drop in priority for Orbit vs other | projects was due to a need to dedicate more time to other | parts of the platform. | | As a large dev/publisher EA has a sizeable central technology | group that develops everything from engines (Frostbite) to | services (EA Digital Platform). | | Ultimately I agree with the philosophy for smaller developers | who are focused purely on making a game, but that's just not | the reality at large companies and ultimately someone has to | develop those services/engines. | ackfoobar wrote: | past: https://news.ycombinator.com/item?id=9300672 | tdstein wrote: | How does this compare to Erlang / Elixir? | sandGorgon wrote: | a very interesting counterpoint is Vert.x - | https://vertx.io/docs/vertx-core/java/ | | Vert.x uses a concept called Verticles - which are like | actors..with an external message bus. Which ends up being more | practical if you start leveraging kafka, etc in the architecture. | spacemanmatt wrote: | Vert.x has grown on me fast! Verticles are the right | combination of actors and good-old pragma. | | The community is healthy and helpful, too. I hope to stick with | Vert.x for a long time even. | voz_ wrote: | Ah GC languages, a curse upon us. | Pxtl wrote: | I assume EA didn't make this just for funsies. What do they use | it for? | [deleted] | baud147258 wrote: | from the article on its release: | | http://blog.bioware.com/2015/03/30/launching-into-orbit/ | | (HN thread: https://news.ycombinator.com/item?id=9300672) | | > The last-generation of Orbit powered some of the key | technology behind the Dragon Age Keep and Dragon Age: | Inquisition. Our plans for the next-generation framework are | even more ambitious. | | So at least it was used for some of Bioware's games | the_arun wrote: | Is actor system same as event based systems or event driven | architecture? | chaostheory wrote: | It's an alternative to working with threads. You pass "work" as | messages to "actors" instead of using locks on resources. | klysm wrote: | Actors are a more specific model of computation. Definitely | related to event based systems but far more specific. | giancarlostoro wrote: | I found out about this one a few years back from a former | (online) friend who worked on it (although I'm not entirely | certain in his specific involvement, I want to say he was the | lead developer initially though), his name is Joe Hegarty[0]. | There was another implementation as well from him in TypeScript | for Node.js called Ratatoskr[1]. | | As far as I've always known him, he always works on networking | projects, I believe he worked on the Fable 3 networking for coop | and several other games. I can't even imagine what he works on at | EA now honestly. | | JoeH if you're reading this by chance: Just remember you were an | inspiration back in the day (mid to late 2000s) to a lot of | people who became developers and learned a ton from your work | back then, myself included. To this day I remember asking you | questions almost every day. Thank you for your efforts and your | patience. | | [0] https://www.joeh.ca/ | | [1] https://github.com/ratatoskr/ratatoskr | JoeHegarty wrote: | Thank you for your kind words. I do indeed still work on | networking stuff. | btbuildem wrote: | I can't help but recoil from a "hello world" that pulls in an | entire container ship of dependencies. | | Especially that we already have a perfectly good, battle- | hardened, and relatively lightweight implementation of Actor | model with Erlang / Elixir. | capableweb wrote: | > I can't help but recoil from a "hello world" that pulls in an | entire container ship of dependencies. | | Where do you see the list of dependencies? Seems to me to be | the ones defined at https://github.com/orbit/orbit/blob/2339560 | 01f1206ccbfde72ef..., is that correct? Doesn't look like "an | entire container ship" but maybe the NPM madness have ruined | me. | | > Especially that we already have a perfectly good, battle- | hardened, and relatively lightweight implementation of Actor | model with Erlang / Elixir. | | Yeah, if you're already using Erland or Elixir, why don't you | go with that instead? This seems to be for the JVM, so one | could assume that the ones who want to use this, is already | invested heavily in the JVM ecosystem (which as far as I know, | EA is when it comes to backend servers). | verst wrote: | The OSS project I work on, Dapr (Distributed Application Runtime | - an incubated CNCF project) implements the virtual actor pattern | if anyone is interested. | | https://docs.dapr.io/developing-applications/building-blocks... | | https://github.com/dapr/dapr | asabla wrote: | Been digging my self deeper and deeper into Dapr, Orleans and | similar for several years now. | | Super cool tech! so thank you for your contributions and future | work on this. | g051051 wrote: | It'd be a lot more interesting if it wasn't in Kotlin. | qlm wrote: | Why does that matter? Kotlin has interop with other JVM | languages. | guipsp wrote: | It does seem that some of the more interesting features | require kotlin, which makes calling it an actor system for | the jvm a bit meh, in my opinion. | spacemanmatt wrote: | You might be a candidate for Vert.x | wiseowise wrote: | Why? | michaelcampbell wrote: | To me it makes it that much more interesting, but reasonable | people can disagree. | newobj wrote: | "Exactly one" is a hard concept to get right. How do they ensure | that exactly one instance of an actor is alive at once, without | sacrificing latency of actor start and/or while tolerating | network partitions? | ackfoobar wrote: | https://proto.actor/docs/cluster-partitions/#multiple-activa... | | > This can be prevented by persisting state in a database with | some form of CAS operations, e.g. Couchbase. | mirekrusin wrote: | That's still "at most one" - ie. even though state of | database itself is "exactly one" (...can "hold the lock") - | the fact that actor thread is remote, it means it can be | partitioned/starve the rest of the system. | | "Exactly once" can be achieved with "at least once" + | _local_, reliable state where you can resolve/ignore | duplicates. But if that "local" state is actually "remote" - | well, then you loose this guarantee (because you can be | arbitrarily partitioned from that state so you're in square | one again). | lichtenberger wrote: | Does anyone know how it compares to Akka? | ackfoobar wrote: | At a glance: | | Sending a message is simply a function call. Whereas in Akka | it's the ask pattern where you have to manually reify the | function call parameters into a case class. | | If you want to wait in processing a message in Akka, you either | have to juggle the message queue with stashing or block a | thread. In Orbit it is a `suspend` fun. | joostdevries wrote: | It's an interesting idea; not having to stash messages in the | actor implementation when doing an async call. I did a little | experiment what that could look like using Akka and kotlin | suspend functions https://github.com/joost-de-vries/akka- | kotlin | slantedview wrote: | I wonder what problems this project aimed to solve that Akka | didn't already solve. | gentleman11 wrote: | > Orbit is a framework to write distributed systems using virtual | actors on the JVM. A virtual actor is an object that interacts | with the world using asynchronous messages. | | Could anybody elaborate on this? How does an actor differ from an | object that uses promises to talk to a server? | mjburgess wrote: | Yip, that's basically just an actor. | | When people talk about actor-based languages or frameworks | however, theyre suggesting syntax primitives which help express | this more naturally. | | The simple pitch is: OO _where_ objects could be on any | machine. | dordoka wrote: | It implements the actor model paradigm. Check this video | https://www.youtube.com/watch?v=7erJ1DV_Tlo | pdpi wrote: | Objects, actors, and (micro-)services are basically the exact | same concept at different scales. | usrusr wrote: | Thanks for making me feel old by not including agents in the | list. Those seem even more similar to actors. At least until | someone mentions BDI, then it's suddenly an entirely | different universe. | spinningslate wrote: | To some approximation. The Actor Model formalism [0] requires | certain properties, notably: | | 1. Communication solely by asynchronous message passing | | 2. A mailbox per actor that means the reception of messages | and the processing of them is decoupled (i.e. an actor can | receive new messages even when processing a previously- | received message). | | The OO model in general supports that paradigm. Pretty much | all mainstream OO languages are synchronous by default | though. Call a method and the caller is suspended until the | method returns. Multiple clients can call methods on the same | object concurrently, but doing that safely requires some form | of locking/protection to be implemented in the target object. | Stated alternatively: threads in mainstream OO languages run | "across" objects, whereas each actor has its own thread in | the Actor model. | | There are certainly similarities - in the sense that both | actors and objects encapsulate state, with reading/writing | occurring through well-defined interfaces (messages and | methods respectively). But the threading model is quite | different - it's not just a matter of scale. | | [0] https://en.wikipedia.org/wiki/Actor_model | | EDIT: corrected grammar & formatting. | asadawadia wrote: | actor model has nothing to do with promises | beardedetim wrote: | Usually the difference is the "mailbox" an actor has, making | the difference more about the level you're calling an actor | more than the differences in any code you might write. | diroussel wrote: | It's not the same as async objects. There are differences | between different score systems. But have a look at Elang and | Akka for example. | | But I'm actor systems the actors maybe more stateful that you | typical object and be location transparent. Communication | between actors does require knowledge of if another actor is in | process or remote. | | Also the actor supervising model is a completely different way | of recovering from errors than in OO systems. | ctvo wrote: | This is a very broad question. I would start with understanding | the concept of actors. You'll end up reading about Erlang, | Akka, etc. | | Then what's a virtual actor and how does it differ? You'll | eventually end up at the Orleans paper from MSFT research: | | https://www.microsoft.com/en-us/research/publication/orleans... | | It really has nothing to do with promises (as used | colloquially) and is a way to design large distributed systems | using message passing and localized state that's persisted. | whoisthemachine wrote: | A promise is a specific class of an actor - | https://en.wikipedia.org/wiki/Futures_and_promises#Semantics... | xeromal wrote: | This is based on a popular and fundamental computer science | paradigm. If you're not familiar with it, it's a good read. | | https://en.wikipedia.org/wiki/Actor_model | birdyrooster wrote: | Highly suggested watch the creator of the actor model explain | to some skeptics. https://youtu.be/7erJ1DV_Tlo | yashap wrote: | Actors are useful for keeping code clean/understandable/correct | when dealing with heavy concurrency AND lots of mutable state. | | Actors are like objects, but the only way to interact with them | is sending them a message - you can't directly access their | properties, call their methods, etc. Messages are bits of | immutable data sent between actors asynchronously, but those | messages go into the actor's mailbox, and then the actor | processes them synchronously, one at a time. You can get | parallelism by adding more actors of the same type (10 actors | of the same type lets you process up to 10 messages | concurrently). Because actors are totally synchronous | INTERNALLY, and nobody can directly access their internal | state, it's fine for them to have mutable internal state, with | no locking/synchronization needed, and much easier to reason | about than mutable state normally is in highly concurrent | applications. | | With that being said, the actor model has a lot of inherent | complexity. If you don't need it, don't use it. But if you | really do need lots of concurrency and lots of mutable state, | it's often a great choice. | | They're also good for distributed systems. Actors only | communicate by sending messages to other actors, but it doesn't | really matter if that message is sent in memory to an actor in | the same process, or over the network to an actor on a | different machine. So you can take a single actor system and | split it across many machines pretty easily. Generally the | actor framework you're using will handle delivering messages | over the network, ensuring there's the right number of actors | running across all nodes combined, etc. | jfoutz wrote: | I've read about actors from time to time for decades. I can't | say I fully grok the concept. | | Kubelet wasn't necessarily designed as an actor. I think it's | a concrete thing that people have interacted with that is a | pretty good example of an actor. It has it's own control | loop. It sits there and actively monitors the state of the | node. It constantly reports the state. If something's wrong, | it can try to correct it. | | Most services and objects just sort of sit around and wait to | be called. Kubelet is a little different, it's got a main | driving thread that's constantly looking for trouble, and | acting on what it finds. | | The line is still pretty fuzzy for me, but maybe this helps | someone connect some conceptual dots, to distinguish between | a service and an actor. | dragonwriter wrote: | > Actors are like objects, but the only way to interact with | them is sending a message - you can't access their | properties, call their methods, etc. | | While the implementation in many popular, e.g. C++ and family | descended from it, languages muddies the waters, basically | methods in OO are a convenient way to define handlers for | messages sent to objects, and in pure OO you also can't | interact with objects except by sending messages to them. The | difference between the basic OO model and the actor model is | that OO message sends are synchronous request/response and | actor model message sends are asynchronous fire-and-forget. | zo1 wrote: | So much this. This "actor model" thing as described by GP | sounds like plain old OO and RPC with extra steps and also | distributed. This may be a low-effort post on my part, but | I'm 100% not impressed because it sounds like marketing | fluff and an opportunity to rewrite native/built-in things | using frameworks. Also justifying Yet Another Framework or | tool hosted on an .IO domain (snarky I know) for promotions | and endless blog posts. | macintux wrote: | Erlang is decades old, a highly successful (for a | relatively niche language, anyway) proof that the actor | model (or something approximating it) can be a great | tool. | astrange wrote: | CSP/actors is from the 70s, like most CS. It is sort of | the original OO, but that's because OO is a newer version | that's both less powerful and over-complicated. | | It doesn't need to be distributed, and it's better not to | include that because the approach to error handling gets | a lot easier. If you're distributed every call can fail, | be randomly slow, has marshaling costs, is untrusted, | etc. | yashap wrote: | Agreed, although it's not always fire-and-forget (i.e. send | a message and don't wait for a response). Actors generally | do support request/response style messaging, but it's | always async - it's really only synchronous | request/response communication that's not allowed. | ryukafalz wrote: | Not always. Goblins[0] is an example of an actor system | that supports both synchronous and asynchronous | communication between actors, with synchronous | communication only possible if both actors are in the | same "vat" (a kind of event loop). | | [0] https://docs.racket-lang.org/goblins/ | dragonwriter wrote: | > Agreed, although it's not always fire-and-forget (i.e. | send a message and don't wait for a response). | | Sure, you can do async request/response in the actor | model, but the low-level basic mechanism all | communication is built on is send a message to an actor | mailbox and keep going. Everything else is built in top | of that. | activitypea wrote: | Excellent description of the actor model, thank you! | spinningslate wrote: | > those messages go into the actor's mailbox, and then the | actor processes them synchronously | | Not trying to be pedantic, but that's technically not true of | the Actor formalism [0]. Quoting wikipedia: | | > an actor can designate the behavior to be used to process | the next message, and then in fact begin processing another | message M2 before it has finished processing M1. | | Available implementations (such as Erlang, Akka, Pony) do not | support that pipelining so are single threaded per actor as | you state though. As an aside, the behaviour you describe | _is_ part of the CSP formalism [1] - a related but different | approach to concurrent systems. | | [0]: https://en.wikipedia.org/wiki/Actor_model#Inherently_con | curr... | | [1]: https://en.wikipedia.org/wiki/Communicating_sequential_p | roce... | throwawaymaths wrote: | Just to be a bit pedantic (but important), Erlang is _not_ | an actor system. It 's a system designed for fault | tolerance and definable failure domains. Concurrency fell | out of those requirements and it just happens to vaguely | look like an actor system if you squint hard enough. I | don't believe theories of actor systems played into the | design of Erlang. | | Perhaps some of the blame belongs on the creators of Erlang | for kind of jumping on the "actor" (and later, "OOP") | bandwagons as marketing? to try to make Erlang less scary. | [deleted] | spinningslate wrote: | Fair point: Erlang wasn't _designed_ as an Actor system. | But you don 't have to squint that hard to see the | similarities. Again quoting wikipedia [0]: | | > An actor is a computational entity that, in response to | a message it receives, can concurrently: | send a finite number of messages to other actors; | create a finite number of new actors; designate | the behavior to be used for the next message it receives. | | > There is no assumed sequence to the above actions and | they could be carried out in parallel. | | All above are true of Erlang except intra-actor | concurrency. Even the last bullet on designating | behaviour: An Erlang process (actor equivalent) can | decide to use a different function when receiving the | next message. It just can't pipeline handling messages. | | So Erlang isn't that far removed from the Actor model in | its behaviour, even if it wasn't designed as an Actor | system in the first place. One might say actors are an | (approximate) emergent property of Erlang rather than an | intentionally designed one. | | Slightly off-topic but the only system I've used that was | designed & built from the outset as an actor system is | Rosette [1]. It was a really interesting project, and | does support pipelining, but has been dormant for more | than a decade. | | [0]: https://en.wikipedia.org/wiki/Actor_model#Fundamenta | l_concep... | | [1]: https://github.com/leithaus/Rosette | | -- | | EDIT: clarified that Rosette is the only system I've | _used_ that was explicitly based on the Actor model from | the outset. | throwawaymaths wrote: | No but also key to the definition of the actor system is | that those are the _only_ things they are allowed to do. | Also, there 's strange stuff like naming processes for | service discovery, and iirc something is wrong with the | way that Erlang does selective receives that disqualifies | it from being an actor system, and ultimately more modern | Erlang things like ets tables and sharing memory with | nifs. | | Point is all of these deviations from actor system were | choices made by the Erlang team in the name of | pragmatism. They all exist because there was a use case | and the first teams using Erlang needed them for | something real; that Erlang is _not_ an actor system is | important, because it 's a highly pragmatic system -- not | one that is based in theory. | galaxyLogic wrote: | > designate the behavior to be used for the next message | it receives. | | I think that is the key insight of actor-systems. | | Actors don't have state. But they can calculate their | replacement based on their immutable data. Thus the way | an actor at a given address evolves is described by the | functions that calculate the successor actors. | | Thus you get Pure Functional Programming implemented on | top of a fabric of distributed evolving entities. You can | understand the behavior and evolution of such a system as | a composition of function-calls, where functions always | produce the same result for the same arguments. | bitwalker wrote: | I mean, if it doesn't count as an implementation of an | actor system, then I'm not sure what does, regardless of | whether it was incidental to the design goals of Erlang | as a language. It certainly walks and quacks like an | actor system in my opinion, and I don't think you have to | squint very hard at all to see it. | | Perhaps we have different ideas of what an "actor system" | is though. | macintux wrote: | Dr. Hewitt typically chimes in on these threads to | emphasize some of the differences between his model and | Erlang. I don't recall his username to locate some of | those. | gentleman11 wrote: | Sounds like an implementation of object oriented programming | as it was originally envisioned | solaxun wrote: | Out of curiosity (not much experience with Actor systems), do | these systems solve a different problem than having disparate | processes communicate by sticking a distributed message queue | between them? From my naive point of view it seems like alot | of the scaling and fault tolerance concerns nowadays can be | solved in any language, by having a queue be the interface | between two services. | | Same question applies to Erlang, which I realize is not | _exactly_ an actor system as per the below comment, and has a | much more sophisticated error recovery story with | supervisors, but the general question holds. | lostcolony wrote: | So I think the Erlang distinction is a little unrelated (I | mean, it's technically accurate, but not because of the | error recovery; that's an implementation detail. The | original Actor formulation Carl Hewitt proposed was heavily | influenced by Smalltalk semantics; whereas Smalltalk was | truly OO, in that everything is an Object that passed | messages, one issue it had was that objects did not equate | to threads of execution. The Actor model, then, said each | object executed independently. But in the same way that | Smalltalk did not have primitives; even integers are always | Objects, the Actor model stipulates there are no | primitives; even integers are Actors). But I'll take a stab | at answering what I think you're asking. | | If your services don't deal with internal mutable state, | nor high degrees of concurrency then there isn't much gain | to be had with an actor system. That said, that begs the | question of what the queue is for; just create more | instances, since there's no internal state to share. | | As soon as you start having internal mutable state and high | levels of concurrency, that's where the actor model | applies. Queues don't exist for concurrency (you don't need | them; just create more executors), they exist for imposing | sequence where it is needed (an obvious case; you have a DB | connection, you want to only have one query at a time. So | every desired query goes into a queue, and the process at | the end that owns the DB connection pulls from it). | Internal mutable state gets stored inside of an actor; | updates and reads get serialized on that actor. | | At the highest level, I would describe the actor model as | taking a 'successful' model for distributed computing, and | making it the only model you use, even locally. | | In, let's say Java, for instance, using standard | concurrency approaches, it matters where a process lives. | My way of operating/communicating to another thread of | execution (unit of concurrency) is very, very different | than my way of operating/communicating to another machine. | Locally I have threads and locks and need to be very | mindful. When communicating to another machine, I send a | message and that's it (maybe I expect a response, and | timeout if I don't get one, but that's really just the same | thing, the other machine sending a message). | | I don't actually need a queue involved for theoretical | correctness unless I need to process messages in sequence | (after all, I could have multiple copies of the other | process, and send a message to each of them). Now, in the | real world I do, simply because if my concurrency gets too | large it can't be handled by what the units of concurrency | already available (instances, threads, whatever), and scale | up takes time, but that's really just a special case of why | I need to impose a sequence on messages (handle these | first, then handle these, rather than handle all of them | concurrently). | | The actor model makes this the local model of communication | (and so makes the impedance mismatch negligible between | local and distributed; so much so that some languages it's | actually irrelevant whether you're sending a message to a | local actor, or a remote one). Scaling concurrency up | internally just means spin up a new actor. When you need to | serialize, you send messages to the same actor, where it | ends up in a queue. | | So it's not solving a different problem, exactly, if that | problem is "how do we write systems that can do multiple | things at once", but the specifics, complexity, etc, tend | to be pretty different. The problems it's solving are a bit | more subjective than simply "can we handle this problem", | and more "how well do our tools and mental model lend | themselves to the problem we're trying to solve". | lostcolony wrote: | >> With that being said, the actor model has a lot of | inherent complexity. If you don't need it, don't use it. But | if you really do need lots of concurrency and lots of mutable | state, it's often a great choice. | | I kind of disagree with this. I mean, it's kind of correct, | if you literally have a sequential problem with immutable | state you're gaining nothing from it, but you're also losing | nothing (you...will have one actor, no messages being passed, | so the only cost is the syntax of the language; the actor | model isn't adding any complexity because you aren't using | it). | | But, a lot of problems we've historically learned to view as | sequential are in fact concurrent. Deeply concurrent. We've | created entire concepts specifically to impose sequential | processing upon innately concurrent activities. | | As an example, almost everywhere we use queues we could | instead model as unrelated processes able to be run | concurrently. You still may have a bit of queueing/scheduling | for unbounded processes, but I know from production | experience that that is far, far simpler to do and get right | using actors than a traditional queue/priority queue and | worker(s). | | And that's where it shines. It encourages you to start | thinking about what in fact -should- be done concurrently, by | making that easy rather than a chore as it is in most other | languages, and that leads to -less- complexity. | bcrosby95 wrote: | I'm curious what you see as so different in an actor vs a | queue with workers. An actor's mailbox effectively acts as | a queue. | | Is it the supporting structure surrounding an actor focused | library/language? Lots of person-hours have gone into | making them to work well. Some home grown queue + pool of | threads working off that queue... not so much. | lostcolony wrote: | So pulling from the alluded to real life example, we | wrote a job scheduling system. Now, each job could be | defined by a lifecycle. It wasn't just a single fire and | forget command, but multiple in time (a prep start, | start, stop, clear, commands), and also tracking status | of an external resource (looking for error states or | ambiguities, etc), and could also be modified (change of | start and stop times, including "now" for both). | | Now, using actors, this was trivial to do. Each actor was | basically a glorified state machine, with each command, | status update, etc, a message coming in that updated the | internal state, and caused it to change state, and, where | appropriate, update anything it needed to (such as the | internal timer for when it would stop the job). We loaded | up everything that had to happen in the next 12 hours, | via an actor that would wake up and load more | periodically (with an actor registry to find and confirm | what existed already, as well as used to route incoming | commands from users to change jobs). There is no | complexity in managing a global state of priority between | the actors; that's a 'solved problem' by the time slicing | the underlying actor engine is doing for us; it's well | tested, well proven, and invisible to us. Our | implementation allows us to treat each job as existing in | isolation, and write our code as though it and it alone | is the job that needs to be executed. There is no global | synchronization state to manage (well, with the caveat of | taking the infinite list of future jobs, and ensuring we | have actual processes equating to those scheduled to | start in the next 12 hours, but that's a comparatively | simple problem, and a proper use of sequential ordering. | We want to execute on _these_ jobs first), nor should | their be based on the problem we 're trying to solve. | | Using a queue and traditional threading model though? | Well, we'd need a synchronized priority queue, as items | could have their priority changed at any time, from | multiple sources. We'd also still need a registry. We'd | need a pool of workers, that are mostly just | blocking...hope we don't have > (number of workers) | things needing to execute concurrently. Our complexity to | manage all of this is high; the level of testing needed | to validate that there aren't emergent bugs, also high. | Our semi-realtime requirements are probably out the | window (high contention on the queue, or high enough | concurrency to exhaust the thread pool could lead to very | measurable delays in updates). And ultimately, it all | comes to the fact that the queue exists to pretend that | the state of the world is sequential, and that we then | had to then contort ourselves around to bring back to a | state that allows for suitable concurrency. Updates to a | job can end up killing a worker and inserting something | back onto the queue, can remove something from the queue | and reinsert it at a different position, etc, all while | other workers are trying to access the queue | simultaneously. | | Actors are the simpler solution. | | The comment about an actor's mailbox being a queue is | missing the point (though, amusingly, demonstrating it). | Queues are sequential. Actors are capable of doing only | one thing at a time, and so when they are requested to do | multiple things, they will do them sequentially. A | mailbox filling with things that don't demand sequential | processing is a code smell in an actor system. This is | useful if you have limited resource access (queries on a | DB connection, say), or need things to be done | sequentially, and are very much akin to threads. But if | you actually want multiple things concurrently...you | should have multiple actors, not send them into the | mailbox of one actor (which is very much the queue | situation mentioned above; you imposed a sequential | ordering on things you want done concurrently. Why?). | That's the key difference; in most other languages, the | queue is taking multiple things you actually want | concurrently, and imposing a sequence to them. In the | actor model, your queue is in fact things you DO want | done sequentially; the things you want done concurrently | should get federated out to multiple actors. | ackfoobar wrote: | You're exactly right. | | Some examples: | | - Some common patterns. E.g. actor hierachy and | supervision, circuit breaker. | | - Persistence. The actor persists its state (changes) and | can wake up from a sleep. | | - Clustering. The actor can live in another node, and you | interact with it using the same API. | ackfoobar wrote: | Well I misread and couldn't edit now. | | What I meant is that you can launch a co/go-routine and | have a channel that only it can read. That is like 70% | the power of having an actor system. | | --- | | > an actor vs _a_ queue with worker _s_ | | See the sibling comment. | | TLDR: Actors each has their own queue. The orderings in | each queue are independent. This can help with | parallelization if it fits the shape of the problem. | dijit wrote: | Orbit is also the name of the always online DRM system that | Ubisoft made many years ago. | | Fun fact, the tech that was developed to power Orbit forked and | evolved along largely divergent paths to be Uplay and the | framework on which the Division and Division 2 online backends | were made. | | You can still see paths referencing Orbit in uplay, especially on | the downloads: | http://static3.cdn.ubi.com/orbit/launcher_installer/UbisoftG... | | Largely C++ on Windows. | [deleted] | shartte wrote: | It looks interesting, but seems to be dead. | | The repository has virtually no activity since september 2020. | ackfoobar wrote: | Oh well, looks like it has the same fate as protoactor-kotlin. ___________________________________________________________________ (page generated 2022-04-28 23:00 UTC)