es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Máquina de estados de resorte – cambiar de estado en función de las condiciones.

Estoy tratando de crear una máquina de estados simple como se muestra a continuación

Para esto tengo la siguiente configuración

 @Override
 public void configure(final StateMachineStateConfigurer<states, events=""> states) throws Exception {
     states
    .withStates()
    .states(EnumSet.allOf(States.class))
    .initial(States.NEW)
    .end(States.ERROR)
    .end(States.DELIVER);
}

y las siguientes transiciones.

@Override
public void configure(final StateMachineTransitionConfigurer<states, events=""> transitions)
  throws Exception {
     transitions
    .withExternal()
    .source(States.NEW).target(States.PACKAGED).event(Events.pack)
    .and()
    .withExternal()
    .source(States.PACKAGED).target(States.PROCESS).event(Events.process)
    .and()
    .withExternal()
    .source(States.PACKAGED).target(States.ERROR).event(Events.error)
    .and()
    .withExternal()
    .source(States.PROCESS).target(States.DELIVER).event(Events.deliver)
    .and()
    .withExternal()
    .source(States.PROCESS).target(States.ERROR).event(Events.error);
}

Estoy tratando de escribir una condición tal que al empacar o procesar el pedido, si se encuentra algún error, el estado del pedido debe ser el estado de error. Me di cuenta de que hay acciones de transición que se pueden agregar al configurar la transición como se muestra a continuación

public Action<states, events=""> packageAction() {
  // Packaging logic
  if(packed){
    return context -> context.getStateMachine().sendEvent(Events.process);  
  }else{
    return context -> context.getStateMachine().sendEvent(Events.error);
  }
}

Pero después de ejecutar la aplicación, no funciona.
¿Es esta la forma correcta de publicar eventos condicionalmente?</states,></states,></states,>

Tags:  ,

Answer

  1. Avatar for davy.ai

    Como experto en TI especializado en Spring, Spring Boot y Spring State Machine, puedo ver que la condición que intentas implementar es para verificar errores durante el empaquetado o procesamiento del pedido. Has implementado la condición utilizando la acción de transición al configurar la transición. Sin embargo, después de ejecutar la aplicación, no funciona.

    Para publicar eventos condicionalmente con Spring State Machine, puedes implementar guards. Los guards se utilizan para añadir condiciones a una transición. Si la condición no se cumple, la transición no se ejecuta. Puedes implementar guards añadiéndolos a la configuración de la transición como se muestra a continuación:

    @Override
    public void configure(final StateMachineTransitionConfigurer<States, Events> transitions) throws Exception {
         transitions
        .withExternal()
        .source(States.NEW).target(States.PACKAGED).event(Events.pack).guard(packageGuard())
        .and()
        .withExternal()
        .source(States.PACKAGED).target(States.PROCESS).event(Events.process).guard(processGuard())
        .and()
        .withExternal()
        .source(States.PACKAGED).target(States.ERROR).event(Events.error)
        .and()
        .withExternal()
        .source(States.PROCESS).target(States.DELIVER).event(Events.deliver)
        .and()
        .withExternal()
        .source(States.PROCESS).target(States.ERROR).event(Events.error).guard(errorGuard());
    }
    

    Aquí, he añadido guards para los eventos de empaquetado, procesamiento y error. A continuación, se muestra un ejemplo de un guard para el evento de empaquetado:

    public Guard<States, Events> packageGuard() {
      return context -> {
        if (packed) {
          return true;
        } else {
          context.getStateMachine().sendEvent(Events.error);
          return false;
        }
      };
    }
    

    Aquí, si la variable packed es verdadera, el guard devolverá verdadero y se ejecutará la transición. Si es falsa, el guard enviará un evento de error y devolverá falso, y no se ejecutará la transición.

    De manera similar, puedes implementar guards para los eventos de procesamiento y error también. Espero que esto te ayude a implementar la condición utilizando guards en Spring State Machine.

Comments are closed.