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