• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2016 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #ifndef GRPCPP_IMPL_CODEGEN_CHANNEL_INTERFACE_H
20 #define GRPCPP_IMPL_CODEGEN_CHANNEL_INTERFACE_H
21 
22 #include <grpc/impl/codegen/connectivity_state.h>
23 #include <grpcpp/impl/codegen/call.h>
24 #include <grpcpp/impl/codegen/status.h>
25 #include <grpcpp/impl/codegen/time.h>
26 
27 namespace grpc {
28 template <class R>
29 class ClientReader;
30 template <class W>
31 class ClientWriter;
32 template <class W, class R>
33 class ClientReaderWriter;
34 namespace internal {
35 template <class InputMessage, class OutputMessage>
36 class CallbackUnaryCallImpl;
37 template <class R>
38 class ClientAsyncReaderFactory;
39 template <class W>
40 class ClientAsyncWriterFactory;
41 template <class W, class R>
42 class ClientAsyncReaderWriterFactory;
43 class ClientAsyncResponseReaderHelper;
44 template <class W, class R>
45 class ClientCallbackReaderWriterFactory;
46 template <class R>
47 class ClientCallbackReaderFactory;
48 template <class W>
49 class ClientCallbackWriterFactory;
50 class ClientCallbackUnaryFactory;
51 }  // namespace internal
52 
53 class ChannelInterface;
54 class ClientContext;
55 class CompletionQueue;
56 
57 namespace experimental {
58 class DelegatingChannel;
59 }
60 
61 namespace internal {
62 class Call;
63 class CallOpSetInterface;
64 class RpcMethod;
65 class InterceptedChannel;
66 template <class InputMessage, class OutputMessage>
67 class BlockingUnaryCallImpl;
68 }  // namespace internal
69 
70 /// Codegen interface for \a grpc::Channel.
71 class ChannelInterface {
72  public:
~ChannelInterface()73   virtual ~ChannelInterface() {}
74   /// Get the current channel state. If the channel is in IDLE and
75   /// \a try_to_connect is set to true, try to connect.
76   virtual grpc_connectivity_state GetState(bool try_to_connect) = 0;
77 
78   /// Return the \a tag on \a cq when the channel state is changed or \a
79   /// deadline expires. \a GetState needs to called to get the current state.
80   template <typename T>
NotifyOnStateChange(grpc_connectivity_state last_observed,T deadline,::grpc::CompletionQueue * cq,void * tag)81   void NotifyOnStateChange(grpc_connectivity_state last_observed, T deadline,
82                            ::grpc::CompletionQueue* cq, void* tag) {
83     TimePoint<T> deadline_tp(deadline);
84     NotifyOnStateChangeImpl(last_observed, deadline_tp.raw_time(), cq, tag);
85   }
86 
87   /// Blocking wait for channel state change or \a deadline expiration.
88   /// \a GetState needs to called to get the current state.
89   template <typename T>
WaitForStateChange(grpc_connectivity_state last_observed,T deadline)90   bool WaitForStateChange(grpc_connectivity_state last_observed, T deadline) {
91     TimePoint<T> deadline_tp(deadline);
92     return WaitForStateChangeImpl(last_observed, deadline_tp.raw_time());
93   }
94 
95   /// Wait for this channel to be connected
96   template <typename T>
WaitForConnected(T deadline)97   bool WaitForConnected(T deadline) {
98     grpc_connectivity_state state;
99     while ((state = GetState(true)) != GRPC_CHANNEL_READY) {
100       if (!WaitForStateChange(state, deadline)) return false;
101     }
102     return true;
103   }
104 
105  private:
106   template <class R>
107   friend class ::grpc::ClientReader;
108   template <class W>
109   friend class ::grpc::ClientWriter;
110   template <class W, class R>
111   friend class ::grpc::ClientReaderWriter;
112   template <class R>
113   friend class ::grpc::internal::ClientAsyncReaderFactory;
114   template <class W>
115   friend class ::grpc::internal::ClientAsyncWriterFactory;
116   template <class W, class R>
117   friend class ::grpc::internal::ClientAsyncReaderWriterFactory;
118   friend class ::grpc::internal::ClientAsyncResponseReaderHelper;
119   template <class W, class R>
120   friend class ::grpc::internal::ClientCallbackReaderWriterFactory;
121   template <class R>
122   friend class ::grpc::internal::ClientCallbackReaderFactory;
123   template <class W>
124   friend class ::grpc::internal::ClientCallbackWriterFactory;
125   friend class ::grpc::internal::ClientCallbackUnaryFactory;
126   template <class InputMessage, class OutputMessage>
127   friend class ::grpc::internal::BlockingUnaryCallImpl;
128   template <class InputMessage, class OutputMessage>
129   friend class ::grpc::internal::CallbackUnaryCallImpl;
130   friend class ::grpc::internal::RpcMethod;
131   friend class ::grpc::experimental::DelegatingChannel;
132   friend class ::grpc::internal::InterceptedChannel;
133   virtual internal::Call CreateCall(const internal::RpcMethod& method,
134                                     ::grpc::ClientContext* context,
135                                     ::grpc::CompletionQueue* cq) = 0;
136   virtual void PerformOpsOnCall(internal::CallOpSetInterface* ops,
137                                 internal::Call* call) = 0;
138   virtual void* RegisterMethod(const char* method) = 0;
139   virtual void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
140                                        gpr_timespec deadline,
141                                        ::grpc::CompletionQueue* cq,
142                                        void* tag) = 0;
143   virtual bool WaitForStateChangeImpl(grpc_connectivity_state last_observed,
144                                       gpr_timespec deadline) = 0;
145 
146   // EXPERIMENTAL
147   // This is needed to keep codegen_test_minimal happy. InterceptedChannel needs
148   // to make use of this but can't directly call Channel's implementation
149   // because of the test.
150   // Returns an empty Call object (rather than being pure) since this is a new
151   // method and adding a new pure method to an interface would be a breaking
152   // change (even though this is private and non-API)
CreateCallInternal(const internal::RpcMethod &,::grpc::ClientContext *,::grpc::CompletionQueue *,size_t)153   virtual internal::Call CreateCallInternal(
154       const internal::RpcMethod& /*method*/, ::grpc::ClientContext* /*context*/,
155       ::grpc::CompletionQueue* /*cq*/, size_t /*interceptor_pos*/) {
156     return internal::Call();
157   }
158 
159   // EXPERIMENTAL
160   // A method to get the callbackable completion queue associated with this
161   // channel. If the return value is nullptr, this channel doesn't support
162   // callback operations.
163   // TODO(vjpai): Consider a better default like using a global CQ
164   // Returns nullptr (rather than being pure) since this is a post-1.0 method
165   // and adding a new pure method to an interface would be a breaking change
166   // (even though this is private and non-API)
CallbackCQ()167   virtual ::grpc::CompletionQueue* CallbackCQ() { return nullptr; }
168 };
169 }  // namespace grpc
170 
171 #endif  // GRPCPP_IMPL_CODEGEN_CHANNEL_INTERFACE_H
172