use of org.apache.nifi.controller.tasks.InvocationResult in project nifi by apache.
the class TimerDrivenSchedulingAgent method createTrigger.
private Runnable createTrigger(final ConnectableTask connectableTask, final LifecycleState scheduleState, final AtomicReference<ScheduledFuture<?>> futureRef) {
final Connectable connectable = connectableTask.getConnectable();
final Runnable yieldDetectionRunnable = new Runnable() {
@Override
public void run() {
// Call the task. It will return a boolean indicating whether or not we should yield
// based on a lack of work for to do for the component.
final InvocationResult invocationResult = connectableTask.invoke();
if (invocationResult.isYield()) {
logger.debug("Yielding {} due to {}", connectable, invocationResult.getYieldExplanation());
}
// If the component is yielded, cancel its future and re-submit it to run again
// after the yield has expired.
final long newYieldExpiration = connectable.getYieldExpiration();
final long now = System.currentTimeMillis();
if (newYieldExpiration > now) {
final long yieldMillis = newYieldExpiration - now;
final long scheduleMillis = connectable.getSchedulingPeriod(TimeUnit.MILLISECONDS);
final ScheduledFuture<?> scheduledFuture = futureRef.get();
if (scheduledFuture == null) {
return;
}
// so that we can do this again the next time that the component is yielded.
if (scheduledFuture.cancel(false)) {
final long yieldNanos = Math.max(TimeUnit.MILLISECONDS.toNanos(scheduleMillis), TimeUnit.MILLISECONDS.toNanos(yieldMillis));
synchronized (scheduleState) {
if (scheduleState.isScheduled()) {
final long schedulingNanos = connectable.getSchedulingPeriod(TimeUnit.NANOSECONDS);
final ScheduledFuture<?> newFuture = flowEngine.scheduleWithFixedDelay(this, yieldNanos, schedulingNanos, TimeUnit.NANOSECONDS);
scheduleState.replaceFuture(scheduledFuture, newFuture);
futureRef.set(newFuture);
}
}
}
} else if (noWorkYieldNanos > 0L && invocationResult.isYield()) {
// Component itself didn't yield but there was no work to do, so the framework will choose
// to yield the component automatically for a short period of time.
final ScheduledFuture<?> scheduledFuture = futureRef.get();
if (scheduledFuture == null) {
return;
}
// so that we can do this again the next time that the component is yielded.
if (scheduledFuture.cancel(false)) {
synchronized (scheduleState) {
if (scheduleState.isScheduled()) {
final ScheduledFuture<?> newFuture = flowEngine.scheduleWithFixedDelay(this, noWorkYieldNanos, connectable.getSchedulingPeriod(TimeUnit.NANOSECONDS), TimeUnit.NANOSECONDS);
scheduleState.replaceFuture(scheduledFuture, newFuture);
futureRef.set(newFuture);
}
}
}
}
}
};
return yieldDetectionRunnable;
}
Aggregations