Check out a free preview of the full State Machines in JavaScript with XState, v2 course

The "Actor Model Q&A" Lesson is part of the full, State Machines in JavaScript with XState, v2 course featured in this preview video. Here's what you'd learn in this lesson:

David answers student's questions regarding what the difference between a service and an actor is and what the difference between spawn and invoke is. Questions regarding if it's possible to send an event from outside the machine if the actor's ID is known and if it's possible to have two separate machines interacting with each other as actors are also covered in this segment.


Transcript from the "Actor Model Q&A" Lesson

>> One question asked is in a nutshell, what is the difference between a service in an actor? The X term service to mean a machine that's interpreted in made into an actor. So, really, there is no difference between a service and an actor right now. A service and an actor are both things where you could send events to.

They could spawn other actors, they could change their own behavior based on what events comes in. And an interesting bit of trivia is that the actor model came into X state later. And so before the actor model, we just called things services. And that's because that's what SC XML called, the things that were or the the interpreted machines and the things that are invoked.

However, they are exactly the same thing. And so when we rewrite the documentation and we move on to version five, that terminology is going to be consolidated. But yeah, a service is an actor. And you could just think of services as actors with state machine behavior. Someone asked can you repeat the difference between spawn and invoke?

So when you invoke an actor, that actor is alive for the duration of what state it's in. We service in the example over here, where this audio actor is only alive while we're in the ready state which is playing or paused. When we skip, that actor gets disposed and then when we go back to the ready state, we have a brand new actor.

When you spawn an actor, that actor is alive until the machine itself is stopped. And so you could also manually stop in a spawned actor. But essentially they're both just actors. It's just one has a different life cycle than the other one. Now the use case of where you will want to spawn an actor which again I encourage you to read up on it.

In the state documentation versus invoking an actor is when you need a dynamic number of actors. For example, let's say that we have a playlist machine. And the playlist spawns dynamically a number of actors and each of these actors are song actors. So we have song, song, song.

This would be a good candidate for spawning actors because invocations are all about, like there being one or a finite number. A predetermined number of actors that represents what's happening in the current states. For these spawn actors, they're not directly tied to a state and there could be just a dynamic number of them.

So we could read from context and be like, okay, I have our playlist. We need to spawn the song actor for each one of these and send events to them individually. That would be a use case for spawned actors which are not tied to a state. Is it possible to send in events from outside any machine if we know the actors ID?

so in general no you cannot do that you need a reference to the actor itself. Thankfully, you can can't have a reference to that actor from from here. So I'm actually gonna type service. Actually, you know what, let's pause this. And let's actually grab it just so I could show you.

Let's see we have window that service. Okay, yeah, so I'm gonna say service.subscribe. Or actually let's just log and see. So service.subscribe, state and we're going to console.log the state. So this date has a property called children. In this these children, each one of these is the invoked actor.

So we have an audio actor and it has a simple interface, just like we built with get snapshot. We have sent, we have subscribe, we have the idea of it, and so you can access this directly and just send it's stuff. So actually, this is interesting. So right now, we are in the past states but what I could do is if I get direct access to this states.

I could say, and I could send it a play events. And so now even though I'm in the past date, it is playing. And so this just goes to show you. Obviously, this should be in the impossible state the song should not be playing. Sorry, impossible behavior, because the song should not be playing while we're in the pause state.

And the reason this happened is because as a human hacker directly got access to that actor. And I sort of sent it information and I told it what to do outside of the parents. So that's like if you again think of this in terms of humans it's like your manager telling you what to do but then someone completely outside the company sneaking into the company and being like hey you should do this instead.

So, obviously that's going to cause some problems. And that's why you shouldn't be just randomly sending actors events. You should be doing so in a controlled way. So I could pause it. Yeah, so you see what happens when we have direct access to an actor or try to access an actor directly when it's not part of the system that we created.

Can I have two separately created machines interact with each other as actors? And so the problem with that is that if you have, let's say, a machine here, in the machine here, they have no way of knowing about each other. You need some sort of glue layer on top of here that sort of knows about both machines and can Past events back and forth between them.

But that becomes an implicit way of modeling that. So instead it's recommended that you have a parent's machine or a parent's actor. However, you want to implement it in this parents actor. Is responsible for spawning both machines and then what it could do is when it spawns the machine.

This parent machine can send a reference to this actor. So if I give this a blue background and this machine or this actor, sort of sense, a reference to that actor as a message then let's lower the opacity. Then now this actor can talk to that actor directly because this parents actor told it about that sibling actor so that's sort of one way of modelling it.

Another way is that you can have this sending events to the parents and make that full. And so that parents can routes that events to the other actor and so this parents essentially becomes a router.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now