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_impl { 28 class ClientContext; 29 class CompletionQueue; 30 template <class R> 31 class ClientReader; 32 template <class W> 33 class ClientWriter; 34 template <class W, class R> 35 class ClientReaderWriter; 36 namespace internal { 37 template <class InputMessage, class OutputMessage> 38 class CallbackUnaryCallImpl; 39 template <class R> 40 class ClientAsyncReaderFactory; 41 template <class W> 42 class ClientAsyncWriterFactory; 43 template <class W, class R> 44 class ClientAsyncReaderWriterFactory; 45 template <class R> 46 class ClientAsyncResponseReaderFactory; 47 template <class W, class R> 48 class ClientCallbackReaderWriterFactory; 49 template <class R> 50 class ClientCallbackReaderFactory; 51 template <class W> 52 class ClientCallbackWriterFactory; 53 class ClientCallbackUnaryFactory; 54 } // namespace internal 55 } // namespace grpc_impl 56 57 namespace grpc { 58 class ChannelInterface; 59 60 namespace experimental { 61 class DelegatingChannel; 62 } 63 64 namespace internal { 65 class Call; 66 class CallOpSetInterface; 67 class RpcMethod; 68 class InterceptedChannel; 69 template <class InputMessage, class OutputMessage> 70 class BlockingUnaryCallImpl; 71 } // namespace internal 72 73 /// Codegen interface for \a grpc::Channel. 74 class ChannelInterface { 75 public: ~ChannelInterface()76 virtual ~ChannelInterface() {} 77 /// Get the current channel state. If the channel is in IDLE and 78 /// \a try_to_connect is set to true, try to connect. 79 virtual grpc_connectivity_state GetState(bool try_to_connect) = 0; 80 81 /// Return the \a tag on \a cq when the channel state is changed or \a 82 /// deadline expires. \a GetState needs to called to get the current state. 83 template <typename T> NotifyOnStateChange(grpc_connectivity_state last_observed,T deadline,::grpc_impl::CompletionQueue * cq,void * tag)84 void NotifyOnStateChange(grpc_connectivity_state last_observed, T deadline, 85 ::grpc_impl::CompletionQueue* cq, void* tag) { 86 TimePoint<T> deadline_tp(deadline); 87 NotifyOnStateChangeImpl(last_observed, deadline_tp.raw_time(), cq, tag); 88 } 89 90 /// Blocking wait for channel state change or \a deadline expiration. 91 /// \a GetState needs to called to get the current state. 92 template <typename T> WaitForStateChange(grpc_connectivity_state last_observed,T deadline)93 bool WaitForStateChange(grpc_connectivity_state last_observed, T deadline) { 94 TimePoint<T> deadline_tp(deadline); 95 return WaitForStateChangeImpl(last_observed, deadline_tp.raw_time()); 96 } 97 98 /// Wait for this channel to be connected 99 template <typename T> WaitForConnected(T deadline)100 bool WaitForConnected(T deadline) { 101 grpc_connectivity_state state; 102 while ((state = GetState(true)) != GRPC_CHANNEL_READY) { 103 if (!WaitForStateChange(state, deadline)) return false; 104 } 105 return true; 106 } 107 108 private: 109 template <class R> 110 friend class ::grpc_impl::ClientReader; 111 template <class W> 112 friend class ::grpc_impl::ClientWriter; 113 template <class W, class R> 114 friend class ::grpc_impl::ClientReaderWriter; 115 template <class R> 116 friend class ::grpc_impl::internal::ClientAsyncReaderFactory; 117 template <class W> 118 friend class ::grpc_impl::internal::ClientAsyncWriterFactory; 119 template <class W, class R> 120 friend class ::grpc_impl::internal::ClientAsyncReaderWriterFactory; 121 template <class R> 122 friend class ::grpc_impl::internal::ClientAsyncResponseReaderFactory; 123 template <class W, class R> 124 friend class ::grpc_impl::internal::ClientCallbackReaderWriterFactory; 125 template <class R> 126 friend class ::grpc_impl::internal::ClientCallbackReaderFactory; 127 template <class W> 128 friend class ::grpc_impl::internal::ClientCallbackWriterFactory; 129 friend class ::grpc_impl::internal::ClientCallbackUnaryFactory; 130 template <class InputMessage, class OutputMessage> 131 friend class ::grpc::internal::BlockingUnaryCallImpl; 132 template <class InputMessage, class OutputMessage> 133 friend class ::grpc_impl::internal::CallbackUnaryCallImpl; 134 friend class ::grpc::internal::RpcMethod; 135 friend class ::grpc::experimental::DelegatingChannel; 136 friend class ::grpc::internal::InterceptedChannel; 137 virtual internal::Call CreateCall(const internal::RpcMethod& method, 138 ::grpc_impl::ClientContext* context, 139 ::grpc_impl::CompletionQueue* cq) = 0; 140 virtual void PerformOpsOnCall(internal::CallOpSetInterface* ops, 141 internal::Call* call) = 0; 142 virtual void* RegisterMethod(const char* method) = 0; 143 virtual void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, 144 gpr_timespec deadline, 145 ::grpc_impl::CompletionQueue* cq, 146 void* tag) = 0; 147 virtual bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, 148 gpr_timespec deadline) = 0; 149 150 // EXPERIMENTAL 151 // This is needed to keep codegen_test_minimal happy. InterceptedChannel needs 152 // to make use of this but can't directly call Channel's implementation 153 // because of the test. 154 // Returns an empty Call object (rather than being pure) since this is a new 155 // method and adding a new pure method to an interface would be a breaking 156 // change (even though this is private and non-API) CreateCallInternal(const internal::RpcMethod &,::grpc_impl::ClientContext *,::grpc_impl::CompletionQueue *,size_t)157 virtual internal::Call CreateCallInternal( 158 const internal::RpcMethod& /*method*/, 159 ::grpc_impl::ClientContext* /*context*/, 160 ::grpc_impl::CompletionQueue* /*cq*/, size_t /*interceptor_pos*/) { 161 return internal::Call(); 162 } 163 164 // EXPERIMENTAL 165 // A method to get the callbackable completion queue associated with this 166 // channel. If the return value is nullptr, this channel doesn't support 167 // callback operations. 168 // TODO(vjpai): Consider a better default like using a global CQ 169 // Returns nullptr (rather than being pure) since this is a post-1.0 method 170 // and adding a new pure method to an interface would be a breaking change 171 // (even though this is private and non-API) CallbackCQ()172 virtual ::grpc_impl::CompletionQueue* CallbackCQ() { return nullptr; } 173 }; 174 } // namespace grpc 175 176 #endif // GRPCPP_IMPL_CODEGEN_CHANNEL_INTERFACE_H 177