> 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?
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 system for the JVM developed by Electronic Arts
51–60 of 95 posts
Re: Actor system for the JVM developed by Electronic Arts
#52Earlier quoted context omitted.
>> 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 a…
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.
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.
Re: Actor system for the JVM developed by Electronic Arts
#53> 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?
Re: Actor system for the JVM developed by Electronic Arts
#54Earlier quoted context omitted.
> 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 send…
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.
Re: Actor system for the JVM developed by Electronic Arts
#55Earlier quoted context omitted.
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…
> 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 send…
Re: Actor system for the JVM developed by Electronic Arts
#56https://docs.dapr.io/developing-applications/building-blocks...
Re: Actor system for the JVM developed by Electronic Arts
#57> 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?
Re: Actor system for the JVM developed by Electronic Arts
#58Earlier quoted context omitted.
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…
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,…
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".
Re: Actor system for the JVM developed by Electronic Arts
#59As 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.
Re: Actor system for the JVM developed by Electronic Arts
#60The 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
Super cool tech! so thank you for your contributions and future work on this.