158 lines
3.7 KiB
Java
158 lines
3.7 KiB
Java
/*
|
|
* Copyright (C) 2009-2019 Lightbend Inc. <https://www.lightbend.com>
|
|
*/
|
|
|
|
package jdocs.actor.fsm;
|
|
|
|
// #simple-imports
|
|
import akka.actor.AbstractFSM;
|
|
import akka.actor.ActorRef;
|
|
import akka.japi.pf.UnitMatch;
|
|
import java.util.Arrays;
|
|
import java.util.LinkedList;
|
|
import java.util.List;
|
|
import java.time.Duration;
|
|
// #simple-imports
|
|
|
|
import static jdocs.actor.fsm.Buncher.Data;
|
|
import static jdocs.actor.fsm.Buncher.State.*;
|
|
import static jdocs.actor.fsm.Buncher.State;
|
|
import static jdocs.actor.fsm.Buncher.Uninitialized.*;
|
|
import static jdocs.actor.fsm.Events.*;
|
|
|
|
// #simple-fsm
|
|
public class Buncher extends AbstractFSM<State, Data> {
|
|
{
|
|
// #fsm-body
|
|
startWith(Idle, Uninitialized);
|
|
|
|
// #when-syntax
|
|
when(
|
|
Idle,
|
|
matchEvent(
|
|
SetTarget.class,
|
|
Uninitialized.class,
|
|
(setTarget, uninitialized) ->
|
|
stay().using(new Todo(setTarget.getRef(), new LinkedList<>()))));
|
|
// #when-syntax
|
|
|
|
// #transition-elided
|
|
onTransition(
|
|
matchState(
|
|
Active,
|
|
Idle,
|
|
() -> {
|
|
// reuse this matcher
|
|
final UnitMatch<Data> m =
|
|
UnitMatch.create(
|
|
matchData(
|
|
Todo.class,
|
|
todo ->
|
|
todo.getTarget().tell(new Batch(todo.getQueue()), getSelf())));
|
|
m.match(stateData());
|
|
})
|
|
.state(
|
|
Idle,
|
|
Active,
|
|
() -> {
|
|
/* Do something here */
|
|
}));
|
|
// #transition-elided
|
|
|
|
when(
|
|
Active,
|
|
Duration.ofSeconds(1L),
|
|
matchEvent(
|
|
Arrays.asList(Flush.class, StateTimeout()),
|
|
Todo.class,
|
|
(event, todo) -> goTo(Idle).using(todo.copy(new LinkedList<>()))));
|
|
|
|
// #unhandled-elided
|
|
whenUnhandled(
|
|
matchEvent(
|
|
Queue.class,
|
|
Todo.class,
|
|
(queue, todo) -> goTo(Active).using(todo.addElement(queue.getObj())))
|
|
.anyEvent(
|
|
(event, state) -> {
|
|
log()
|
|
.warning(
|
|
"received unhandled request {} in state {}/{}",
|
|
event,
|
|
stateName(),
|
|
state);
|
|
return stay();
|
|
}));
|
|
// #unhandled-elided
|
|
|
|
initialize();
|
|
// #fsm-body
|
|
}
|
|
// #simple-fsm
|
|
|
|
static
|
|
// #simple-state
|
|
// states
|
|
enum State {
|
|
Idle,
|
|
Active
|
|
}
|
|
|
|
// #simple-state
|
|
static
|
|
// #simple-state
|
|
// state data
|
|
interface Data {}
|
|
|
|
// #simple-state
|
|
static
|
|
// #simple-state
|
|
enum Uninitialized implements Data {
|
|
Uninitialized
|
|
}
|
|
|
|
// #simple-state
|
|
static
|
|
// #simple-state
|
|
final class Todo implements Data {
|
|
private final ActorRef target;
|
|
private final List<Object> queue;
|
|
|
|
public Todo(ActorRef target, List<Object> queue) {
|
|
this.target = target;
|
|
this.queue = queue;
|
|
}
|
|
|
|
public ActorRef getTarget() {
|
|
return target;
|
|
}
|
|
|
|
public List<Object> getQueue() {
|
|
return queue;
|
|
}
|
|
// #boilerplate
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "Todo{" + "target=" + target + ", queue=" + queue + '}';
|
|
}
|
|
|
|
public Todo addElement(Object element) {
|
|
List<Object> nQueue = new LinkedList<>(queue);
|
|
nQueue.add(element);
|
|
return new Todo(this.target, nQueue);
|
|
}
|
|
|
|
public Todo copy(List<Object> queue) {
|
|
return new Todo(this.target, queue);
|
|
}
|
|
|
|
public Todo copy(ActorRef target) {
|
|
return new Todo(target, this.queue);
|
|
}
|
|
// #boilerplate
|
|
}
|
|
// #simple-state
|
|
// #simple-fsm
|
|
}
|
|
// #simple-fsm
|