1 /* 2 * Copyright 2017 Google LLC 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google LLC nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 package com.google.api.gax.longrunning; 31 32 import com.google.api.core.ApiFuture; 33 import com.google.api.gax.retrying.RetryingFuture; 34 import java.util.concurrent.ExecutionException; 35 36 /** 37 * An ApiFuture which tracks polling of a service. The polling is done periodically, based on the 38 * {@link com.google.api.gax.retrying.TimedRetryAlgorithm}. 39 * 40 * <p>Implementations are expected to be thread-safe. 41 */ 42 public interface OperationFuture<ResponseT, MetadataT> extends ApiFuture<ResponseT> { 43 /** 44 * Returns the value of the name of the operation from the initial operation object returned from 45 * the initial call to start the operation. Blocks if the initial call to start the operation 46 * hasn't returned yet. 47 */ getName()48 String getName() throws InterruptedException, ExecutionException; 49 50 /** 51 * Returns the {@link OperationSnapshot} future of the initial request which started this {@code 52 * OperationFuture}. 53 */ getInitialFuture()54 ApiFuture<OperationSnapshot> getInitialFuture(); 55 56 /** Returns the {@link RetryingFuture} which continues to poll {@link OperationSnapshot}. */ getPollingFuture()57 RetryingFuture<OperationSnapshot> getPollingFuture(); 58 59 /** 60 * Peeks at the metadata of the operation tracked by this {@link OperationFuture}. If the initial 61 * future hasn't completed yet this method returns {@code null}, otherwise it returns the latest 62 * metadata returned from the server (i.e. either initial call metadata or the metadata received 63 * from the latest completed poll iteration). 64 * 65 * <p>If not {@code null}, the returned result is guaranteed to be an already completed future, so 66 * {@link ApiFuture#isDone()} will always be {@code true} and {@link ApiFuture#get()} will always 67 * be non-blocking. 68 * 69 * <p>Note, some APIs may return {@code null} in metadata response message. In such cases this 70 * method may return a non-null future whose {@code get()} method will return {@code null}. This 71 * behavior is API specific an should be considered a valid case, which indicates that the recent 72 * poll request has completed, but no specific metadata was provided by the server (i.e. most 73 * probably providing metadata for an intermediate result is not supported by the server). 74 * 75 * <p>This method should be used to check operation progress without blocking current thread. 76 * Since this method returns metadata from the latest completed poll, it is potentially slightly 77 * stale compared to the most recent data. To get the most recent data and/or get notified when 78 * the current scheduled poll request completes use the {@link #getMetadata()} method instead. 79 * 80 * <p>If this operation future is completed, this method always returns the metadata from the last 81 * poll request (which completed the operation future). 82 * 83 * <p>If this operation future failed, this method may (depending on the failure type) return a 84 * non-failing future, representing the metadata from the last poll request (which failed the 85 * operation future). 86 * 87 * <p>If this operation future was cancelled, this method returns a canceled metatata future as 88 * well. 89 * 90 * <p>In general this method behaves similarly to {@link RetryingFuture#peekAttemptResult()}. 91 */ peekMetadata()92 ApiFuture<MetadataT> peekMetadata(); 93 94 /** 95 * Gets the metadata of the operation tracked by this {@link OperationFuture}. This method returns 96 * the current poll metadata result (or the initial call metadata if it hasn't completed yet). The 97 * returned future completes once the current scheduled poll request (or the initial request if it 98 * hasn't completed yet) is executed and response is received from the server. The time when the 99 * polling request is executed is determined by the underlying polling algorithm. 100 * 101 * <p>Adding direct executor (same thread) callbacks to the future returned by this method is 102 * strongly not recommended, since the future is resolved under retrying future's internal lock 103 * and may affect the operation polling process. Adding separate thread callbacks is ok. 104 * 105 * <p>Note, some APIs may return {@code null} in metadata response message. In such cases this 106 * method may return a non-null future whose {@code get()} method will return {@code null}. This 107 * behavior is API specific an should be considered a valid case, which indicates that the recent 108 * poll request has completed, but no specific metadata was provided by the server. (i.e. most 109 * probably providing metadata for an intermediate result is not supported by the server). 110 * 111 * <p>In most cases this method returns a future which is not completed yet, so calling {@link 112 * ApiFuture#get()} is a potentially blocking operation. To get metadata without blocking the 113 * current thread use the {@link #peekMetadata()} method instead. 114 * 115 * <p>If this operation future is completed, this method always returns the metadata from the last 116 * poll request (which completed the operation future). 117 * 118 * <p>If this operation future failed, this method may (depending on the failure type) return a 119 * non-failing future, representing the metadata from the last poll request (which failed the 120 * operation future). 121 * 122 * <p>If this operation future was cancelled, this method returns a canceled metatata future as 123 * well. 124 * 125 * <p>In general this method behaves similarly to {@link RetryingFuture#getAttemptResult()}. 126 */ getMetadata()127 ApiFuture<MetadataT> getMetadata(); 128 } 129