Running Side Effects
Emitting effects on another component
An Entity or an Action may also emit one or more side effects. A side effect is something whose result has no impact on the result of the current command—if it fails, the current command still succeeds. The result of the side effect is therefore ignored. When used from inside an Entity, side effects are only performed after the successful completion of any state actions requested by the command handler.
There is no guarantee that a side effect will be executed successfully. If a failure occurs after the command is fully handled, effects might not be executed. Side effects are not retried in case of failures.
Side effects may be declared as synchronous or asynchronous. Asynchronous commands run in a "fire and forget" fashion. The code flow of the caller (the command handler of the entity which emitted the asynchronous command) continues while the command is being asynchronously processed. Meanwhile, synchronous commands run sequentially, that is, the commands are processed in order, one at a time. The final result of the command handler, either a reply or a forward, is not sent until all synchronous commands are completed.
Emitting a side effect
To illustrate how you can emit a side effect, you can build on top of the Action as a Controller example. In that previous example, you build a controller around the Value Entity Counter and forwarded the incoming request after modifying it.
This time, instead of using a forward
, you will call the entity using a side effect.
Implementing the Action
The class DoubleCounterAction
listens to the counter state changes. When the counter value changes this action doubles doubles it.
public Action.Effect<Confirmed> increaseWithSideEffect(Number increase){
var counterId = actionContext().eventSubject().get(); (1)
var doubleIncrease = increase.value() * 2; (2)
var deferredCall = kalixClient.post("/counter/" + counterId + "/increase/" + doubleIncrease, Number.class);
return effects().reply(Confirmed.instance).addSideEffect(SideEffect.of(deferredCall)); (3)
}
1 | Retrieving the id of the counter. |
2 | On incoming request, doubling the value of increase . |
3 | Building a reply using Confirmed.getDefaultInstance() . And attaching a side effect, i.e. calling to the Counter to increase double the previous amount. |
Please note that, the response of the side effect is ignored by the command meaning that even if the deferred call to
the Counter
entity fails, the Action
reply will succeed.