public State < T > onEvent ( T stateful , String event , Object ... args ) throws TooBusyException { int attempts = 0 ; while ( this . retryAttempts == - 1 || attempts < this . retryAttempts ) { try { State < T > current = this . getCurrentState ( stateful ) ; // Fetch the transition for this event from the current state // Transition < T > transition = this . getTransition ( event , current ) ; // Is there one? // if ( transition != null ) { current = this . transition ( stateful , current , event , transition , args ) ; } else { if ( logger . isDebugEnabled ( ) ) logger . debug ( "{}({})::{}({})->{}/noop" , this . name , stateful . getClass ( ) . getSimpleName ( ) , current . getName ( ) , event , current . getName ( ) ) ; // If blocking, force a transition to the current state as // it's possible that another thread has moved out of the blocking state. // Either way, we'll retry this event // if ( current . isBlocking ( ) ) { this . setCurrent ( stateful , current , current ) ; throw new WaitAndRetryException ( this . retryInterval ) ; } } return current ; } catch ( RetryException re ) { logger . warn ( "{}({})::Retrying event" , this . name , stateful ) ; // Wait? // if ( WaitAndRetryException . class . isInstance ( re ) ) { try { Thread . sleep ( ( ( WaitAndRetryException ) re ) . getWait ( ) ) ; } catch ( InterruptedException ie ) { throw new RuntimeException ( ie ) ; } } attempts ++ ; } } logger . error ( "{}({})::Unable to process event" , this . name , stateful ) ; throw new TooBusyException ( ) ; }
Process event . Will handle all retry attempts . If attempts exceed maximum retries it will throw a TooBusyException .