This post is the second of a two-part series of articles on Stackable Traits, click here to view Part I.
Gathering metrics with stackable actors
We like to gather the following metrics:
The time from the moment a message was enqueued into an actor’s mailbox until the moment it was dequeued for processing.
How long did it take for the actor to process a message?
And to log when an actor starts handling a message and before it finishes.
Stackable actor-based implementation
Say we have the following actor that we like to monitor:
Let’s start with the ‘time-in-mailbox’ metric. The simplest way to implement it is to take the time before the message was sent and calculate the time in the mailbox when the actor starting processing it.
For the sake of example, we’ll assume that a message was created just before it was sent.
The message class that should be monitored is:
We initialized the time before the message was sent, and gave it a name, to be used as a tag for the metric.
Next, create the stackable trait for monitoring the actor on RecordableMessage:
You might notice that:
- As discussed in Part I, the modifier of the ‘receive’ method should be “abstract override”
- We gather the metrics only on the ‘RecordableMessage’ message
- For calculating ‘time-in-mailbox’, ‘dispatchTime’ is used
- For calculating ‘processing-time’, we take time before invoking the action, then invoking the action, and record the ‘processing-time’ when it finished.
The LoggerActor is the following:
Lastly, mix these traits to a concrete MyActor class
class MyMonitoredActor extends MyActor with LatencyRecorderActor with LoggerActor
And we ended up with:
Try it out
Create a concrete RecordableMessage:
And send it to a MonitoredActor instance
Results with the following printed to the log:
Stackable trait patterns are a good choice when you need to ‘pipe’ actions or modify and redirect data for an action.
Mix and stack traits to describe the state of the class and execute the actions are clean and flexible, and generally the Scala-functional way to do it.