Repository navigation
Activation
As shown in the Lifecycle diagram a message processor can be created for one of two reasons: when a message comes in for a message processor that hasn't been created yet, or when the message processor is configured to be pre-instantiated. In either of these cases it will be cloned from the prototype and any method annotated with the @Activation annotation will be invoked.
There are several reasons you might want to use the @Activation annotation:
The simplest reason is that the message processor can be provided the message key during @Activation. Recall our WordCount example. Let's suppose that the WordCount message processor needed the word that it was keeping the count for. This might be the case if it needed to emit a subsequent message with the count and its text, for processing further downstream (see the example in the section on Non-stream Driven Message Processor Output). In that case the message handler would need to look something like this:
String wordKey = null;
@MessageHandler
public void countWord(Word word)
{
if (wordKey == null)
{
wordKey = word.getWordText();
}
count++;
}This need is more often the case than not. Notice that annoying piece of boilerplate code (the if clause) that will appear in every message processor that needs to know its key. This code will execute every time the message processor receives a message, even though it only serves a purpose the first time it's used.
Instead, if the method annotated with @Activation takes the key, then the container will invoke that method immediately after the message processor is instantiated, and pass it the key. The following is the alternative:
String wordKey = null;
@Activation
public void setWordText(String key)
{
wordKey = key;
}
@MessageHandler
public void countWord(Word word)
{
count++;
}Another reason for implementing an @Activation method is state management. For stateful message processors the @Activation provides a hook for the message processor to load its state from an external store.
Keep in mind that even though there is a @Passivation that can be used to write data to an external store, because of node failures you are not guaranteed that a previous @Passivation was called even if this message processor was recently receiving messages on another node.
When a message processor is moved from one node to another due to the need to rebalance load (e.g. when a new node enters the cluster, or an existing node leaves the cluster), then the message processor will be passivated in one node, and activated in the other node.
Note: this is still under design: Dempsy will provide a means of serializing state information to be passed between the two nodes by means of the return value of the @Passivation, and a respective input parameter on the @Activation method.
To receive notifications when a message processor is being evicted from the container, you can use the @Passivation annotation. Methods annotated with @Passivation will be called when:
- An eviction policy is defined for the message processor and as a result the container has determined that the message processor needs to be removed.
- The container is being shut down gracefully which causes the
@Passivationto be invoked on every message processor currently in the container. - As part of transporting a message processor from one node to another during elastic rebalancing due to the addition or removal of a node from the cluster.
Next section: Non-stream Driven Message Processor Output