Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve fsm #943

Merged
merged 6 commits into from
Jun 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 13 additions & 20 deletions common/src/main/java/bisq/common/fsm/Fsm.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,12 @@

@Slf4j

public class Fsm {
public class Fsm<M extends FsmModel> {
private final Map<Pair<State, Class<? extends Event>>, Transition> transitionMap = new HashMap<>();
private final Object lock = new Object();
@Getter
private final FsmModel model;
protected final M model;

public Fsm(State initialState) {
this(new FsmModel(initialState));
}

public Fsm(FsmModel model) {
public Fsm(M model) {
this.model = model;
configTransitions();
}
Expand All @@ -52,7 +47,7 @@ protected void configTransitions() {
public void handle(Event event) throws FsmException {
try {
checkNotNull(event, "event must not be null");
synchronized (lock) {
synchronized (this) {
State currentState = model.getState();
checkNotNull(currentState, "currentState must not be null");
if (currentState.isFinalState()) {
Expand Down Expand Up @@ -87,38 +82,36 @@ private void addTransition(Transition transition) throws FsmException {
Pair<State, Class<? extends Event>> pair = new Pair<>(transition.getSourceState(), transition.getEventClass());
checkArgument(!transitionMap.containsKey(pair),
"A transition exists already with the state/event pair. pair=%s", pair);
synchronized (lock) {
transitionMap.put(pair, transition);
}
transitionMap.put(pair, transition);
} catch (Exception e) {
throw new FsmException(e);
}
}

public TransitionBuilder addTransition() {
return new TransitionBuilder(this);
public TransitionBuilder<M> addTransition() {
return new TransitionBuilder<>(this);
}

public static class TransitionBuilder {
public static class TransitionBuilder<M extends FsmModel> {
private final Transition transition;
private final Fsm fsm;
private final Fsm<M> fsm;

private TransitionBuilder(Fsm fsm) {
private TransitionBuilder(Fsm<M> fsm) {
this.fsm = fsm;
transition = new Transition();
}

public TransitionBuilder from(State sourceState) {
public TransitionBuilder<M> from(State sourceState) {
transition.setSourceState(sourceState);
return this;
}

public TransitionBuilder on(Class<? extends Event> eventClass) {
public TransitionBuilder<M> on(Class<? extends Event> eventClass) {
transition.setEventClass(eventClass);
return this;
}

public TransitionBuilder run(Class<? extends EventHandler> eventHandlerClass) {
public TransitionBuilder<M> run(Class<? extends EventHandler> eventHandlerClass) {
try {
transition.setEventHandlerClass(Optional.of(eventHandlerClass));
} catch (Exception e) {
Expand Down
44 changes: 22 additions & 22 deletions common/src/test/java/bisq/common/fsm/FsmTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
import static org.junit.jupiter.api.Assertions.assertNull;

public class FsmTest {
// @Test
@Test
void testValidStateTransitions() throws FsmException {
MockModel model = new MockModel(MockState.INIT);
Fsm fsm = new Fsm(model);
Fsm<MockModel> fsm = new Fsm<>(model);

// No change in data as no handler was defined
fsm.addTransition()
Expand Down Expand Up @@ -66,7 +66,7 @@ void testValidStateTransitions() throws FsmException {
@Test
void testTransitions() throws FsmException {
MockModel model = new MockModel(MockState.INIT);
Fsm fsm = new Fsm(model);
Fsm<MockModel> fsm = new Fsm<>(model);

// No change in data as no handler was defined
fsm.addTransition()
Expand Down Expand Up @@ -107,11 +107,11 @@ void testTransitions() throws FsmException {
assertEquals("test4", model.data);
}

// @Test
@Test
void testNoStateTransition() throws FsmException {
// No such event defined: No state change, no handler call
MockModel model1 = new MockModel(MockState.INIT);
Fsm fsm1 = new Fsm(model1);
Fsm<MockModel> fsm1 = new Fsm<>(model1);
fsm1.addTransition()
.from(MockState.INIT)
.on(MockEvent1.class)
Expand All @@ -124,7 +124,7 @@ void testNoStateTransition() throws FsmException {
// If no target state is set we do not create the transition, so no exception is thrown but no transition if
// found at handle.
MockModel model2 = new MockModel(MockState.INIT);
Fsm fsm2 = new Fsm(model2);
Fsm<MockModel> fsm2 = new Fsm<>(model2);
fsm2.addTransition()
.from(MockState.INIT)
.on(MockEvent1.class)
Expand All @@ -135,7 +135,7 @@ void testNoStateTransition() throws FsmException {

// If source state is already final we do not transit
MockModel model3 = new MockModel(MockState.COMPLETED);
Fsm fsm3 = new Fsm(model3);
Fsm<MockModel> fsm3 = new Fsm<>(model3);
fsm3.addTransition()
.from(MockState.COMPLETED)
.on(MockEvent1.class)
Expand All @@ -147,7 +147,7 @@ void testNoStateTransition() throws FsmException {

// Same event and state combination: No state change, no handler call
MockModel model4 = new MockModel(MockState.INIT);
Fsm fsm4 = new Fsm(model4);
Fsm<MockModel> fsm4 = new Fsm<>(model4);
fsm4.addTransition()
.from(MockState.INIT)
.on(MockEvent1.class)
Expand All @@ -162,7 +162,7 @@ void testNoStateTransition() throws FsmException {

// No state change as wrong event fired
MockModel model5 = new MockModel(MockState.INIT);
Fsm fsm5 = new Fsm(model5);
Fsm<MockModel> fsm5 = new Fsm<>(model5);
fsm5.addTransition()
.from(MockState.INIT)
.on(MockEvent1.class)
Expand All @@ -173,11 +173,11 @@ void testNoStateTransition() throws FsmException {
assertNull(((MockModel) fsm5.getModel()).data);
}

// @Test
@Test
void testEventHandlerNotCalled() throws FsmException {
// No EventHandlerClass defined
MockModel model1 = new MockModel(MockState.INIT);
Fsm fsm1 = new Fsm(model1);
Fsm<MockModel> fsm1 = new Fsm<>(model1);
fsm1.addTransition()
.from(MockState.INIT)
.on(MockEvent1.class)
Expand All @@ -187,11 +187,11 @@ void testEventHandlerNotCalled() throws FsmException {
assertNull(((MockModel) fsm1.getModel()).data);
}

// @Test
@Test
void testFsmExceptions() throws FsmException {
Assertions.assertThrows(FsmException.class, () -> {
MockModel model = new MockModel(MockState.INIT);
Fsm fsm = new Fsm(model);
Fsm<MockModel> fsm = new Fsm<>(model);
fsm.addTransition()
.from(null)
.on(MockEvent1.class)
Expand All @@ -201,7 +201,7 @@ void testFsmExceptions() throws FsmException {
});
Assertions.assertThrows(FsmException.class, () -> {
MockModel model = new MockModel(MockState.INIT);
Fsm fsm = new Fsm(model);
Fsm<MockModel> fsm = new Fsm<>(model);
fsm.addTransition()
.on(MockEvent1.class)
.run(MockEventHandler.class)
Expand All @@ -210,7 +210,7 @@ void testFsmExceptions() throws FsmException {
});
Assertions.assertThrows(FsmException.class, () -> {
MockModel model = new MockModel(MockState.INIT);
Fsm fsm = new Fsm(model);
Fsm<MockModel> fsm = new Fsm<>(model);
fsm.addTransition()
.from(MockState.INIT)
.on(null)
Expand All @@ -220,7 +220,7 @@ void testFsmExceptions() throws FsmException {
});
Assertions.assertThrows(FsmException.class, () -> {
MockModel model = new MockModel(MockState.INIT);
Fsm fsm = new Fsm(model);
Fsm<MockModel> fsm = new Fsm<>(model);
fsm.addTransition()
.from(MockState.INIT)
.run(MockEventHandler.class)
Expand All @@ -229,7 +229,7 @@ void testFsmExceptions() throws FsmException {
});
Assertions.assertThrows(FsmException.class, () -> {
MockModel model = new MockModel(MockState.INIT);
Fsm fsm = new Fsm(model);
Fsm<MockModel> fsm = new Fsm<>(model);
fsm.addTransition()
.from(MockState.INIT)
.on(MockEvent1.class)
Expand All @@ -239,7 +239,7 @@ void testFsmExceptions() throws FsmException {
});
Assertions.assertThrows(FsmException.class, () -> {
MockModel model = new MockModel(MockState.INIT);
Fsm fsm = new Fsm(model);
Fsm<MockModel> fsm = new Fsm<>(model);
fsm.addTransition()
.from(MockState.INIT)
.on(MockEvent1.class)
Expand All @@ -250,7 +250,7 @@ void testFsmExceptions() throws FsmException {
// Initial state is null
Assertions.assertThrows(FsmException.class, () -> {
MockModel model = new MockModel(null);
Fsm fsm = new Fsm(model);
Fsm<MockModel> fsm = new Fsm<>(model);
fsm.addTransition()
.from(MockState.INIT)
.on(MockEvent1.class)
Expand All @@ -261,7 +261,7 @@ void testFsmExceptions() throws FsmException {
// Same source and target state
Assertions.assertThrows(FsmException.class, () -> {
MockModel model = new MockModel(MockState.INIT);
Fsm fsm = new Fsm(model);
Fsm<MockModel> fsm = new Fsm<>(model);
fsm.addTransition()
.from(MockState.INIT)
.on(MockEvent1.class)
Expand All @@ -273,7 +273,7 @@ void testFsmExceptions() throws FsmException {
// MockEventHandler2 constructor not matching defined constructor signature in newEventHandlerFromClass
Assertions.assertThrows(FsmException.class, () -> {
MockModel model = new MockModel(MockState.INIT);
Fsm fsm = new Fsm(model);
Fsm<MockModel> fsm = new Fsm<>(model);
fsm.addTransition()
.from(MockState.INIT)
.on(MockEvent1.class)
Expand All @@ -285,7 +285,7 @@ void testFsmExceptions() throws FsmException {
// same pair sourceState/event added
Assertions.assertThrows(FsmException.class, () -> {
MockModel model = new MockModel(MockState.INIT);
Fsm fsm = new Fsm(model);
Fsm<MockModel> fsm = new Fsm<>(model);
fsm.addTransition()
.from(MockState.INIT)
.on(MockEvent1.class)
Expand Down
2 changes: 0 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ google-guava-lib = { strictly = '31.1-jre' }

i2p-lib = { strictly = '1.8.0' }
jackson-lib = { strictly = '2.13.3' }
jeasy-easy-states-lib = { strictly = '2.0.0' }
jeromq-lib = { strictly = '0.5.2' }
jpackage-plugin = { strictly = '1.3.1' }
junit-jupiter-lib = { strictly = '5.8.2' }
Expand Down Expand Up @@ -100,7 +99,6 @@ jackson-core = { module = 'com.fasterxml.jackson.core:jackson-core', version.ref
jackson-annotations = { module = 'com.fasterxml.jackson.core:jackson-annotations', version.ref = 'jackson-lib' }
jackson-databind = { module = 'com.fasterxml.jackson.core:jackson-databind', version.ref = 'jackson-lib' }

jeasy-easy-states = { module = 'org.jeasy:easy-states', version.ref = 'jeasy-easy-states-lib' }
jeromq = { module = 'org.zeromq:jeromq', version.ref = 'jeromq-lib' }
junit-jupiter = { module = 'org.junit.jupiter:junit-jupiter', version.ref = 'junit-jupiter-lib' }

Expand Down
1 change: 0 additions & 1 deletion network/network/src/main/java/bisq/network/NetworkId.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@

import static com.google.common.base.Preconditions.checkArgument;

@ToString
@EqualsAndHashCode
@Getter
public final class NetworkId implements Proto {
Expand Down
1 change: 0 additions & 1 deletion trade/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,4 @@ dependencies {

implementation libs.google.guava
implementation libs.typesafe.config
implementation libs.jeasy.easy.states
}
2 changes: 0 additions & 2 deletions trade/src/main/java/bisq/trade/ServiceProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import bisq.identity.IdentityService;
import bisq.network.NetworkService;
import bisq.offer.OfferService;
import bisq.persistence.PersistenceService;
import bisq.support.MediationService;
import bisq.support.SupportService;
import lombok.Getter;
Expand All @@ -38,7 +37,6 @@ public class ServiceProvider {

public ServiceProvider(NetworkService networkService,
IdentityService identityService,
PersistenceService persistenceService,
OfferService offerService,
ContractService contractService,
SupportService supportService) {
Expand Down
Loading