2017-11-24 13 views
0

私はSpring Statemachineにガードを持っています。(UML)Statemachine.stop()の後もSpring Statementが実行されています

@Bean 
public Guard<String, String> myGuard() { 
    return context -> { 
     try { 
      String x = null; 
      x.length(); 
      return true; 
     } catch (Exception e) { 
      context.getStateMachine().setStateMachineError(e); 
      context.getStateMachine().stop(); 
      throw e; 
     } 
    }; 
} 

もちろんこれはjava.lang.NullPointerExceptionです。
私はcontext.getStateMachine().stop();を作ってから、ステーマ機械が止まっていると思っていました。

2017-11-24 18:02:55.783 INFO 30652 --- [nio-8080-exec-1] o.s.s.support.LifecycleObjectSupport  : stopped org.s[email protected]367d6b09 

これで停止しました。 しかし、他のすべての警備員や州や行動よりも後に呼び出されます。

エラーが表示されたら、私は間違いなくガードをfalseに切り替えることは望ましくない、私は本当にマシンを終了したい。

リージョンは1つのみです。だから、私が理解している限り、それはちょうど止まるべきです。

これを処理する方法はありますか?または、これが起こっているときに「終了イベント」のようなものを呼び出す方法はありますか?

私はこれに対処するためのアイデアに感謝しています。

使用:

spring-boot: 1.5.8 
spring-statemachine-uml 1.2.6 

答えて

0

私はこのSpringAOP機能となりましたすべてのエラーをキャッチしています:まだ

if(myStateMachine.hasStateMachineError()) { 
    // do something which is returning the ERROR. 
} 

:私は私のステートマシンを起動

import org.aspectj.lang.annotation.AfterThrowing; 
import org.aspectj.lang.annotation.Aspect; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.statemachine.StateMachine; 
import org.springframework.stereotype.Component;  
import lombok.extern.slf4j.Slf4j; 

@Slf4j 
@Aspect 
@Component 
public class ErrorInterceptor { 

    @Autowired 
    private StateMachine<String, String> myStateMachine; 

    @AfterThrowing(pointcut = "execution(* org.springframework.statemachine.guard.Guard.evaluate(*))", throwing = "ex") 
    public void errorInterceptorGuard(Exception ex) { 
     log.info("Error on Guard: " + myStateMachine.getState().getId() + " with Exception " + ex.toString()); 
     myStateMachine.setStateMachineError(ex); 
    } 

    @AfterThrowing(pointcut = "execution(* org.springframework.statemachine.action.Action.execute(*))", throwing = "ex") 
    public void errorInterceptorAction(Exception ex) { 
     log.info("Error on Action: " + myStateMachine.getState().getId() + " with Exception " + ex.toString()); 
     myStateMachine.setStateMachineError(ex); 
    } 
} 

そして、私のコントローラで

は、私のような何かを作りますstatemachine.stopは内部から作業していないので、私が望むものは100%ではありませんが、私はそれを別のものとして扱っています。

+0

私はこれをこのように使用しようとしたことは一度もなく、あるレベルではこれはあなたがしてはいけないことです。あなたは本質的にマシン内部の仕組みを変更しています。私はおそらく、pointcutsを使うのが合理的で、どれくらいうまくいくか試してみるつもりです。しかし、あなたが達成しようとしていることを説明しようとすることができますか?そうすれば、助けがはるかに簡単になります。 –

+0

私たちはいくつかの貨幣ベースの決定にステートマシンを使用しています。ガードが真実ならば、顧客は300、偽の500、(例として)を得るでしょう。しかし、エラーが発生した場合、それは常に偽になり、より高い金額が支払われます。この時点で私は 'statemachine.setStateMachineError(exception);'のようなことをすることができますし、最後に結果があれば何でも返すことはありません – Joerg

+0

私はtry/catchをアクションに使用して、拡張状態変数。次に、選択肢(基本的には/ elseif/else構造体です)を使用して次の状態を決定し、ガードを使用してどのパスを選択するかを選択します。これは、実際にサポートされていないpointcutsを使用しようとするよりも、物事を行うためのより統計的な方法です。 –

1

私は1つのガードから機械を停止しようとすると、この場合にはどうするかわかりません。正直言って、あなたがしようとしていることが意味をなさないので、私はそれを試したこともありません。どのように私はもともとコンテキストを公開することを選択したことを振り返り、マシン自体にアクセスできるようにして、ストップメソッドを見えるようにしました。私はマシンが動作しているときに内部ロジックからマシンを停止しようとしません。私はずっと前にこのことについて考えていたはずです。

しかし、ガードには本当にトランジションを保護する役割が1つしかなく、真または偽のいずれかを返さなければなりません。ガードが呼び出されたときに例外をキャッチする(我々はそれをfalseに評価する)が、ガードから何かを投げることは、一般的には未定義の動作です。

アクションエラーで何かが起こると仮定すると、それは何らかのエラー関連を行うべきポイントです。つまり、ターミナル状態を作成し、そのターミナル状態への移行を設定し、アクションから(catch内の)イベントを送信して、その状態になるようにマシンに指示することができます。通常、この種のエラー処理は、通常はすべての状態からエラー状態への遷移を開始する必要がある状態の爆発を引き起こすため、シングルルートレベルのマシンでは実行されません。そのため、通常、適切なエラー処理を処理するためにサブ状態が使用されます。

しかし、あなたのユースケースをもう少し開いて、達成したいことがあれば、私はより良い例を挙げることができます。エラー処理は、通常、マシン設計に組み込む必要があるため、常に特定のトピックです。私が現在spring-cloud-skipperで作業しているものを処理するもう少し洗練されたエラーは、下の状態図から見ることができます。これはおそらくあなたの質問の範囲外ですが、あなたの次のコメントの背景を示します。

statechart

+0

はUMLであり、これはどこかオンラインでのプログラミングですか?私たちは持っていないので、私たちはすべてを1つにまとめました。 – Joerg

+1

実際のマシン設定はJavaベースです。私は単にpapyrusを使ってステートチャートを描きました。まだマージされていませんが、私の枝にありますhttps://github.com/jvalkeal/spring-cloud-skipper/tree/sm-work-16/spring-cloud-skipper-server-core/src/main/java/org/スプリングフレームワーク/クラウド/スキッパー/サーバー/ステートマシン。現在のより正確なスタートチャートはhttps://github.com/spring-cloud/spring-cloud-skipper/issues/234から見つけることができます。 –

+0

大丈夫です、私たちはこれを見て..... ..... お時間をありがとう。 – Joerg

関連する問題