spring-projects / spring-statemachine

Spring Statemachine is a framework for application developers to use state machine concepts with Spring.
1.57k stars 616 forks source link

How get a persisted StateMachine #827

Open FabianoLothor opened 4 years ago

FabianoLothor commented 4 years ago

I have the code below

    public StateMachine<CustomStates, CustomEvents> getRecomendacaoMachine(UUID uuid) {
        var stateMachine = factory.getStateMachine(uuid);
        stateMachine.start();

        try {
            var key = CACHE_KEY + stateMachine.getUuid().toString();
//            var ctx = redisStateMachineContextRepo.getContext(key);
            redisStateMachinePersister.restore(stateMachine, key);
        } catch (Exception e) {
            log.error(e.getMessage());
        }

        return stateMachine;
    }

But the function always returns a new State Machine.

My question is how can I get the State Machine from Redis.

The commented line returns correctly the context, but... I need the Persisted StateMachine.

thdghgns commented 4 years ago

@FabianoLothor

I used StateMachineService.acquireStateMachine(machineId) in my case, I used mysql and jpa to persist statemachine context.

configuration

@Autowired
JpaStateMachineRepository jpaStateMachineRepository;

@Bean("issueStateMachineRuntimePersister")
public StateMachineRuntimePersister<IssueStates, IssueEvents, String> issueStateMachineRuntimePersister() {
    return new JpaPersistingStateMachineInterceptor<>(jpaStateMachineRepository);
}

@Bean
public StateMachineService<IssueStates, IssueEvents> issueStateMachineService(@Qualifier("issueStateMachineFactory") StateMachineFactory<IssueStates, IssueEvents> issueStateMachineFactory,
                                                               @Qualifier("issueStateMachineRuntimePersister") StateMachineRuntimePersister<IssueStates, IssueEvents, String> issueStateMachineRuntimePersister) {
    return new DefaultStateMachineService<IssueStates, IssueEvents>(issueStateMachineFactory, issueStateMachineRuntimePersister);
}

usage in controller code

@PostMapping("/issue")
public String createIssue(@RequestBody IssueDto.Create issue) {
    // issue number
    UUID uuid = UUID.randomUUID();
    StateMachine<IssueStates, IssueEvents> stateMachine =  stateMachineService.acquireStateMachine(uuid.toString());

    return stateMachine.getId();
}

@GetMapping("/issue")
public void getIssue(@RequestParam(name = "uuid") String name) throws Exception {
    UUID uuid = UUID.fromString(name);
    StateMachine<IssueStates, IssueEvents> stateMachine = stateMachineService.acquireStateMachine(uuid.toString());

}

@PutMapping("/issue")
public void updateIssue(@RequestParam(name = "uuid") String name,
                        @RequestParam(name = "event") IssueEvents event) throws Exception {
    UUID uuid = UUID.fromString(name);
    StateMachine<IssueStates, IssueEvents> stateMachine = stateMachineService.acquireStateMachine(uuid.toString());
    stateMachine.sendEvent(event);
}
FabianoLothor commented 4 years ago

@thdghgns It is been a while, I don't have sure, but if my brain it is working nice, the problem here, was because of I was using devtools, and for some reason, the create function it was always returning me a new SM.