@Override public void execute(Props parentProps, final FlowCallback callback) { if (parentProps == null) { parentProps = new Props(); } synchronized (sync) { if (this.parentProps == null) { this.parentProps = parentProps; } else if (jobState != Status.COMPLETED && !this.parentProps.equalsProps(parentProps)) { throw new IllegalArgumentException( String.format( "%s.execute() called with multiple differing parentProps objects. " + "Call reset() before executing again with a different Props object. this.parentProps[%s], parentProps[%s]", getClass().getSimpleName(), this.parentProps, parentProps)); } switch (jobState) { case READY: jobState = Status.RUNNING; callbacksToCall.add(callback); break; case RUNNING: callbacksToCall.add(callback); return; case COMPLETED: case SUCCEEDED: case IGNORED: callback.completed(Status.SUCCEEDED); return; case FAILED: callback.completed(Status.FAILED); return; } } if (startTime == null) { startTime = new DateTime(); } for (ExecutableFlow flow : flows) { if (jobState != Status.FAILED) { try { flow.execute(this.parentProps, theGroupCallback); } catch (RuntimeException e) { final List<FlowCallback> callbacks; synchronized (sync) { jobState = Status.FAILED; callbacks = callbacksToCall; } callCallbacks(callbacks, Status.FAILED); throw e; } } } }
@Override public void progressMade() { final List<FlowCallback> callbackList; synchronized (sync) { callbackList = callbacksToCall; } for (FlowCallback flowCallback : callbackList) { flowCallback.progressMade(); } }
private void callCallbacks(final List<FlowCallback> callbacksList, final Status status) { if (endTime == null) { endTime = new DateTime(); } for (FlowCallback callback : callbacksList) { try { callback.completed(status); } catch (RuntimeException t) { // TODO: Figure out how to use the logger to log that a callback threw an exception. } } }
@Override public void completed(final Status status) { final List<FlowCallback> callbackList; synchronized (sync) { updateState(); callbackList = callbacksToCall; // Get the reference before leaving the synchronized } if (jobState == Status.SUCCEEDED && notifiedCallbackAlready.compareAndSet(false, true)) { callCallbacks(callbackList, Status.SUCCEEDED); } else if (jobState == Status.FAILED && notifiedCallbackAlready.compareAndSet(false, true)) { for (ExecutableFlow flow : flows) { exceptions.putAll(flow.getExceptions()); } callCallbacks(callbackList, Status.FAILED); } else { for (FlowCallback flowCallback : callbackList) { flowCallback.progressMade(); } } }