• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 The gRPC Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package io.grpc;
18 
19 import static com.google.common.base.Preconditions.checkNotNull;
20 
21 import com.google.common.base.MoreObjects;
22 import javax.annotation.concurrent.ThreadSafe;
23 
24 /**
25  * {@link StreamTracer} for the client-side.
26  */
27 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2861")
28 @ThreadSafe
29 public abstract class ClientStreamTracer extends StreamTracer {
30   /**
31    * The call was delayed due to waiting for name resolution result.
32    */
33   public static final CallOptions.Key<Boolean> NAME_RESOLUTION_DELAYED =
34       CallOptions.Key.createWithDefault("io.grpc.ClientStreamTracer.NAME_RESOLUTION_DELAYED",
35           false);
36 
37   /**
38    * The stream is being created on a ready transport.
39    *
40    * @param headers the mutable initial metadata. Modifications to it will be sent to the socket but
41    *     not be seen by client interceptors and the application.
42    *
43    * @since 1.40.0
44    */
streamCreated(@rpc.TransportAttr Attributes transportAttrs, Metadata headers)45   public void streamCreated(@Grpc.TransportAttr Attributes transportAttrs, Metadata headers) {
46   }
47 
48   /**
49    * Name resolution is completed and the connection starts getting established. This method is only
50    * invoked on the streams that encounter such delay.
51    *
52    * </p>gRPC buffers the client call if the remote address and configurations, e.g. timeouts and
53    * retry policy, are not ready. Asynchronously gRPC internally does the name resolution to get
54    * this information. The streams that are processed immediately on ready transports by the time
55    * the RPC comes do not go through the pending process, thus this callback will not be invoked.
56    */
createPendingStream()57   public void createPendingStream() {
58   }
59 
60   /**
61    * Headers has been sent to the socket.
62    */
outboundHeaders()63   public void outboundHeaders() {
64   }
65 
66   /**
67    * Headers has been received from the server.
68    */
inboundHeaders()69   public void inboundHeaders() {
70   }
71 
72   /**
73    * Trailing metadata has been received from the server.
74    *
75    * @param trailers the mutable trailing metadata.  Modifications to it will be seen by
76    *                 interceptors and the application.
77    * @since 1.17.0
78    */
inboundTrailers(Metadata trailers)79   public void inboundTrailers(Metadata trailers) {
80   }
81 
82   /**
83    * Factory class for {@link ClientStreamTracer}.
84    */
85   public abstract static class Factory {
86     /**
87      * Creates a {@link ClientStreamTracer} for a new client stream.  This is called inside the
88      * transport when it's creating the stream.
89      *
90      * @param info information about the stream
91      * @param headers the mutable headers of the stream. It can be safely mutated within this
92      *        method.  Changes made to it will be sent by the stream.  It should not be saved
93      *        because it is not safe for read or write after the method returns.
94      *
95      * @since 1.20.0
96      */
newClientStreamTracer(StreamInfo info, Metadata headers)97     public ClientStreamTracer newClientStreamTracer(StreamInfo info, Metadata headers) {
98       throw new UnsupportedOperationException("Not implemented");
99     }
100   }
101 
102   /**
103    * Information about a stream.
104    *
105    * <p>Note this class doesn't override {@code equals()} and {@code hashCode}, as is the case for
106    * {@link CallOptions}.
107    *
108    * @since 1.20.0
109    */
110   @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2861")
111   public static final class StreamInfo {
112     private final CallOptions callOptions;
113     private final int previousAttempts;
114     private final boolean isTransparentRetry;
115 
StreamInfo( CallOptions callOptions, int previousAttempts, boolean isTransparentRetry)116     StreamInfo(
117         CallOptions callOptions, int previousAttempts, boolean isTransparentRetry) {
118       this.callOptions = checkNotNull(callOptions, "callOptions");
119       this.previousAttempts = previousAttempts;
120       this.isTransparentRetry = isTransparentRetry;
121     }
122 
123     /**
124      * Returns the effective CallOptions of the call.
125      */
getCallOptions()126     public CallOptions getCallOptions() {
127       return callOptions;
128     }
129 
130     /**
131      * Returns the number of preceding attempts for the RPC.
132      *
133      * @since 1.40.0
134      */
getPreviousAttempts()135     public int getPreviousAttempts() {
136       return previousAttempts;
137     }
138 
139     /**
140      * Whether the stream is a transparent retry.
141      *
142      * @since 1.40.0
143      */
isTransparentRetry()144     public boolean isTransparentRetry() {
145       return isTransparentRetry;
146     }
147 
148     /**
149      * Converts this StreamInfo into a new Builder.
150      *
151      * @since 1.21.0
152      */
toBuilder()153     public Builder toBuilder() {
154       return new Builder()
155           .setCallOptions(callOptions)
156           .setPreviousAttempts(previousAttempts)
157           .setIsTransparentRetry(isTransparentRetry);
158     }
159 
160     /**
161      * Creates an empty Builder.
162      *
163      * @since 1.21.0
164      */
newBuilder()165     public static Builder newBuilder() {
166       return new Builder();
167     }
168 
169     @Override
toString()170     public String toString() {
171       return MoreObjects.toStringHelper(this)
172           .add("callOptions", callOptions)
173           .add("previousAttempts", previousAttempts)
174           .add("isTransparentRetry", isTransparentRetry)
175           .toString();
176     }
177 
178     /**
179      * Builds {@link StreamInfo} objects.
180      *
181      * @since 1.21.0
182      */
183     public static final class Builder {
184       private CallOptions callOptions = CallOptions.DEFAULT;
185       private int previousAttempts;
186       private boolean isTransparentRetry;
187 
Builder()188       Builder() {
189       }
190 
191       /**
192        * Sets the effective CallOptions of the call.  This field is optional.
193        */
setCallOptions(CallOptions callOptions)194       public Builder setCallOptions(CallOptions callOptions) {
195         this.callOptions = checkNotNull(callOptions, "callOptions cannot be null");
196         return this;
197       }
198 
199       /**
200        * Set the number of preceding attempts of the RPC.
201        *
202        * @since 1.40.0
203        */
setPreviousAttempts(int previousAttempts)204       public Builder setPreviousAttempts(int previousAttempts) {
205         this.previousAttempts = previousAttempts;
206         return this;
207       }
208 
209       /**
210        * Sets whether the stream is a transparent retry.
211        *
212        * @since 1.40.0
213        */
setIsTransparentRetry(boolean isTransparentRetry)214       public Builder setIsTransparentRetry(boolean isTransparentRetry) {
215         this.isTransparentRetry = isTransparentRetry;
216         return this;
217       }
218 
219       /**
220        * Builds a new StreamInfo.
221        */
build()222       public StreamInfo build() {
223         return new StreamInfo(callOptions, previousAttempts, isTransparentRetry);
224       }
225     }
226   }
227 }
228