/**
     * Executes the given task (supplier) in the gRPC context executor of this client, such that if the context is
     * cancelled (e.g. client shutdown) the RPC is automatically cancelled.
     * <p>
     * Important: Tasks submitted in parallel by different threads are forced executed sequentially.
     * <p>
     */
private <U> CompletableFuture<U> supplyInContext(Supplier<U> supplier, String opDescription) {
        return CompletableFuture.supplyAsync(() -> {
            // TODO: explore a more relaxed locking strategy.
            writeLock.lock();
            try {
                return supplier.get();
            } catch (Throwable ex) {
                log.error("Exception in P4Runtime client of {}, executing {}", deviceId, opDescription, ex);
                throw ex;
            } finally {
                writeLock.unlock();
            }
        }, contextExecutor);
    }
private <U> CompletableFuture<U> supplyInContext(Supplier<U> supplier, String opDescription) {
return CompletableFuture.supplyAsync(() -> {
// TODO: explore a more relaxed locking strategy.
writeLock.lock();
try {
return supplier.get();
} catch (Throwable ex) {
log.error("Exception in P4Runtime client of {}, executing {}", deviceId, opDescription, ex);
throw ex;
} finally {
writeLock.unlock();
}
}, contextExecutor);
}
private <U> CompletableFuture<U> supplyInContext(Supplier<U> supplier, String opDescription) {
return CompletableFuture.supplyAsync(() -> {
// TODO: explore a more relaxed locking strategy.
writeLock.lock();
try {
return supplier.get();
} catch (Throwable ex) {
log.error("Exception in P4Runtime client of {}, executing {}", deviceId, opDescription, ex);
throw ex;
} finally {
writeLock.unlock();
}
}, contextExecutor);
}
private <U> CompletableFuture<U> supplyInContext(Supplier<U> supplier, String opDescription) {
return CompletableFuture.supplyAsync(() -> {
// TODO: explore a more relaxed locking strategy.
writeLock.lock();
try {
return supplier.get();
} catch (Throwable ex) {
log.error("Exception in P4Runtime client of {}, executing {}", deviceId, opDescription, ex);
throw ex;
} finally {
writeLock.unlock();
}
}, contextExecutor);
}