left-icon

Akka.NET Succinctly®
by Zoran Maksimovic

Previous
Chapter

of
A
A
A

CHAPTER 6

The Actor’s Switchable Behavior

The Actor’s Switchable Behavior


Actors intrinsically have the ability to change their behavior at runtime! What do we mean by behavior? An actor’s behavior is its ability to react differently to the received message, depending on the conditions.

When the actor starts, it has its own default behavior, which means that the function to be executed when the message is received is set up at that point. However, this function might change based on some conditions. For instance, if the client is not authorized to execute something, the actor can switch the behavior and deny any further execution.

Why is behavior interesting? One way of implementing behaviors would be to put conditional statements (if, then, else) all over the place in order to deal with a particular condition (is call authorized). Instead, the actor model solves this by allowing you to switch to a different message processor, so when the next message comes, this will be executed within the new behavior.

There is no limit on how many behaviors an actor may have, and changing of behavior is handled by the function Become(). After we call Become(), the previous behavior is forgotten unless we use the BecomeStacked() function, which creates a stack of behaviors, so that the behavior can be reverted by using UnbecomeStacked().

Note: The change in the behavior always applies to the next message to be processed.

The following example will illustrate how this looks in practice.

Music player example

As an example of how the behavior can be used within an actor, we are going to build a little music player. This is a very simple example that hopefully will make it easy to understand the whole behavior concept.

The music player we are building accepts two message types, and has some rules:

  • PlaySongMessage: Instructs the player to start playing a song. The rule is that the player cannot play another song if a song is already playing.
  • StopPlayingMessage: Instructs the player to stop playing a song. If we stop an already stopped player, nothing happens.

This means that the music player has two behaviors (or states): one in which a song is currently being played, and one in which the player is stopped.

The following is the very simple definition of these two messages:

Code Listing 44: Music player input messages definition

public class PlaySongMessage

{

    public PlaySongMessage(string song)

    {

        Song = song;

    }

    public string Song { get; }

}

public class StopPlayingMessage

{

}

As we can see, the StopPlayingMessage class is pretty much a marker to instruct the player to stop playing. There is no additional information, as it’s not needed. We know there can be only one song played at a time.

On the other hand, the PlaySongMessage has an attribute called Song, which represents the song name.

The actor we are going to create is called MusicPlayerActor, and will inherit from the ReceiveActor base class, which we have previously discussed.

Code Listing 45: Definition of the MusicPlayerActor

public class MusicPlayerActor : ReceiveActor

{

    protected string CurrentSong;

    public MusicPlayerActor()

    {

        StoppedBehavior();

    }

    private void StoppedBehavior()

    {

        Receive<PlaySongMessage>(m => PlaySong(m.Song));

        Receive<StopPlayingMessage>(m =>

                       Console.WriteLine("Cannot stop, the actor is already stopped"));

    }

    private void PlayingBehavior()

    {

        Receive<PlaySongMessage>(m =>

                 Console.WriteLine($"Cannot play. Currently playing '{CurrentSong}'"));

        Receive<StopPlayingMessage>(m => StopPlaying());

    }

    private void PlaySong(string song)

    {

        CurrentSong = song;

        Console.WriteLine($"Currently playing '{CurrentSong}'");

        Become(PlayingBehavior);

    }

    private void StopPlaying()

    {

        CurrentSong = null;

        Console.WriteLine($"Player is currently stopped.");

        Become(StoppedBehavior);

    }

}

After looking at the content of the actor, we can see there are two methods that define a behavior of an actor, as explained in Table 4.

Table 4: Music player behaviors

PlayingBehavior()

The behavior used while the song is playing.

It handles both messages, and it’s set once the song starts playing. It returns an error message (actually just a console message) if a new message to play a song (PlaySongMessage) is being sent.

It responds to the StopPlayingMessage, as it will make sure that the music player stops.

StoppedBehavior()

The behavior used while the player is stopped.

It handles both messages, and it’s set at the creation of the actor (see the constructor).

It returns an error message if we try to stop the already-stopped music player.

We are setting the behavior of the actor by simply creating the two methods that will decide what happens to the messages being handled.

In Code Listing 45, we can see how the Become method is being used to switch to the new behavior. We use Become just after we stop the player, or start playing a new song. Very straightforward!

One thing to note is the fact that the music player actor has a state, defined by the CurrentSong property, which is set every time we play a new song. This shows how an actor can hold state. We mentioned that one of the attributes of an actor is that it has a state, and this is exactly it! It’s not any different from a typical usage of a class, as we used when working with C#.

Let’s see how to call the actor by starting and playing various songs.

Code Listing 46: Client code for running the music player

static void Main(string[] args)

{

    ActorSystem system = ActorSystem.Create("my-first-akka");

    IActorRef musicPlayer = system.ActorOf<MusicPlayerActor>("musicPlayer");

    musicPlayer.Tell(new PlaySongMessage("Smoke on the water"));

    musicPlayer.Tell(new PlaySongMessage("Another brick in the wall"));

    musicPlayer.Tell(new StopPlayingMessage());

    musicPlayer.Tell(new StopPlayingMessage());

    musicPlayer.Tell(new PlaySongMessage("Another brick in the wall"));

    Console.Read();

    system.Terminate();

}

Figure 20 shows the output after running the Main method.

Result of playing the music

Figure 20: Result of playing the music

We can see that if we try to play a new song while the previous song is being played, the following message is displayed: Cannot play. Currently playing ‘Smoke on the water’.

In the same way, if we try to stop an already-stopped music player, the following message will be shown: Cannot stop, the actor is already stopped.

Scroll To Top
Disclaimer
DISCLAIMER: Web reader is currently in beta. Please report any issues through our support system. PDF and Kindle format files are also available for download.

Previous

Next



You are one step away from downloading ebooks from the Succinctly® series premier collection!
A confirmation has been sent to your email address. Please check and confirm your email subscription to complete the download.