All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.trino.operator.DriverYieldSignal Maven / Gradle / Ivy

There is a newer version: 465
Show newest version
/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.trino.operator;

import com.google.common.annotations.VisibleForTesting;
import com.google.errorprone.annotations.ThreadSafe;
import com.google.errorprone.annotations.concurrent.GuardedBy;

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.atomic.AtomicBoolean;

import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkState;
import static java.util.concurrent.TimeUnit.NANOSECONDS;

/**
 * Methods setWithDelay and reset should be used in pairs;
 * usually follow the following idiom:
 * 
 {@code
 * DriverYieldSignal signal = ...;
 * signal.setWithDelay(duration, executor);
 * try {
 *     // block
 * } finally {
 *     signal.reset();
 * }
 * }
*/ @ThreadSafe public class DriverYieldSignal { @GuardedBy("this") private long runningSequence; @GuardedBy("this") private boolean terminationStarted; @GuardedBy("this") private ScheduledFuture yieldFuture; private final AtomicBoolean yield = new AtomicBoolean(); public synchronized void setWithDelay(long maxRunNanos, ScheduledExecutorService executor) { checkState(yieldFuture == null, "there is an ongoing yield"); checkState(!isSet(), "yield while driver was not running"); if (terminationStarted) { return; } this.runningSequence++; long expectedRunningSequence = this.runningSequence; yieldFuture = executor.schedule(() -> { synchronized (this) { if (expectedRunningSequence == runningSequence && yieldFuture != null) { yield.set(true); } } }, maxRunNanos, NANOSECONDS); } public synchronized void reset() { if (terminationStarted) { return; } checkState(yieldFuture != null, "there is no ongoing yield"); yield.set(false); yieldFuture.cancel(true); yieldFuture = null; } public boolean isSet() { return yield.get(); } /** * Signals an immediate yield to the driver to improve responsiveness to termination commands that may arrive while drivers are * still running. After calling this method, the driver should not attempt to start another interval of running and attempting * to call {@link DriverYieldSignal#setWithDelay(long, ScheduledExecutorService)} will fail. */ public synchronized void yieldImmediatelyForTermination() { terminationStarted = true; yield.set(true); if (yieldFuture != null) { yieldFuture.cancel(true); yieldFuture = null; } } @Override public synchronized String toString() { return toStringHelper(this) .add("yieldScheduled", yieldFuture != null) .add("yield", yield.get()) .toString(); } @VisibleForTesting public synchronized void forceYieldForTesting() { yield.set(true); } @VisibleForTesting public synchronized void resetYieldForTesting() { yield.set(false); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy