Workflow
Properties
It could be useful to expose public properties of our workflow. We will illustrate this with the small example of a very simple loyalty program:
public class LoyaltyImpl extends Workflow implements Loyalty {
private final Integer weekSeconds = 3600*24*7;
private Integer points = 0;
@Override
public void start() {
Instant now = inline(Instant::now);
int w = 0;
while (w < 56) {
// every week, a new point is added
w++;
timer(now.plusSeconds(w * weekSeconds)).await();
points++;
}
}
}
class LoyaltyImpl : Workflow(), Loyalty {
private val weekSeconds = 3600*24*7;
private var points = 0
override fun start() {
val now = inline { Instant.now() }
var w = 0
while (w < 56) {
// every week, a new point is added
w++
timer(now.plusSeconds((w * weekSeconds).toLong())).await()
points++
}
}
}
The workflow above basically increment a points
counter every week for a year. Note how easy it is to code it using Infinitic!
Now, we will see:
- how to know the current values of
points
- how to add bonus points for exceptional events
Getting workflow properties
To get the current values of points
, we only need to add a getter to it in the workflow interface (in Kotlin, we only need to set points
as public to create the corresponding getter/setter):
public class LoyaltyImpl extends Workflow implements Loyalty {
private Integer points = 0;
@Override
public Integer getPoints() {
return points;
}
...
}
class LoyaltyImpl : Workflow(), Loyalty {
var points = 0
...
}
That's all we need, as a client (or another workflow) can now access the value of points
by targeting the right workflow and synchrously running the getter method on it (as explained here):
Loyalty loyalty = client.getWorkflowById(Loyalty.class, id);
Integer points = loyalty.getPoints();
val loyalty = client.getWorkflowById(Loyalty::class.java, id)
val points = loyalty.points
Of course, if needed, we can apply a similar technique for setters!
Trigger action on a running workflow
Let's add a method adding points for exceptional events:
public class LoyaltyImpl extends Workflow implements Loyalty {
...
@Override
public void addBonus(BonusEvent event) {
switch (event) {
case REGISTRATION_COMPLETED:
points+= 100;
break;
case FORM_COMPLETED:
points+= 200;
break;
case ORDER_COMPLETED:
points+= 500;
break;
}
}
...
}
class LoyaltyImpl : Workflow(), Loyalty {
...
override fun addBonus(event: BonusEvent) {
points += when (event) {
BonusEvent.REGISTRATION_COMPLETED -> 100
BonusEvent.FORM_COMPLETED -> 200
BonusEvent.ORDER_COMPLETED -> 500
}
}
}
That's basically all we need. Now, we can add bonus points from a client:
Loyalty loyalty = client.getWorkflowById(Loyalty.class, id);
client.dispatchVoid(loyalty::addBonus, BonusEvent.REGISTRATION_COMPLETED);
val loyalty = client.getWorkflowById(Loyalty::class.java, id)
client.dispatch(loyalty::addBonus, BonusEvent.REGISTRATION_COMPLETED)
or from another workflow:
Loyalty loyalty = getWorkflowById(Loyalty.class, id);
dispatchVoid(loyalty::addBonus, BonusEvent.REGISTRATION_COMPLETED);
val loyalty = getWorkflowById(Loyalty::class.java, id)
dispatch(loyalty::addBonus, BonusEvent.REGISTRATION_COMPLETED)
Of course, from there it's easy to enrich the workflow behavior, for example by adding actions when a user reaches different threshold points.
@Ignore annotation
The @Ignore
(io.infinitic.annotations.Ignore
) annotation lets us tag properties that are not part of the workflow state and should not be serialized during the workflow execution.
Service stubs, Workflow stubs and Channels are automatically ignored and are not saved with the workflow state.