Workflows
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 weekInSeconds = 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 * weekInSeconds)).await();
points++;
}
}
}
class LoyaltyImpl : Workflow(), Loyalty {
private val weekInSeconds = 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 * weekInSeconds).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.