/* * * Copyright 2016 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef GRPCPP_IMPL_CODEGEN_CHANNEL_INTERFACE_H #define GRPCPP_IMPL_CODEGEN_CHANNEL_INTERFACE_H #include #include #include #include namespace grpc { template class ClientReader; template class ClientWriter; template class ClientReaderWriter; namespace internal { template class CallbackUnaryCallImpl; template class ClientAsyncReaderFactory; template class ClientAsyncWriterFactory; template class ClientAsyncReaderWriterFactory; class ClientAsyncResponseReaderHelper; template class ClientCallbackReaderWriterFactory; template class ClientCallbackReaderFactory; template class ClientCallbackWriterFactory; class ClientCallbackUnaryFactory; } // namespace internal class ChannelInterface; class ClientContext; class CompletionQueue; namespace experimental { class DelegatingChannel; } namespace internal { class Call; class CallOpSetInterface; class RpcMethod; class InterceptedChannel; template class BlockingUnaryCallImpl; } // namespace internal /// Codegen interface for \a grpc::Channel. class ChannelInterface { public: virtual ~ChannelInterface() {} /// Get the current channel state. If the channel is in IDLE and /// \a try_to_connect is set to true, try to connect. virtual grpc_connectivity_state GetState(bool try_to_connect) = 0; /// Return the \a tag on \a cq when the channel state is changed or \a /// deadline expires. \a GetState needs to called to get the current state. template void NotifyOnStateChange(grpc_connectivity_state last_observed, T deadline, ::grpc::CompletionQueue* cq, void* tag) { TimePoint deadline_tp(deadline); NotifyOnStateChangeImpl(last_observed, deadline_tp.raw_time(), cq, tag); } /// Blocking wait for channel state change or \a deadline expiration. /// \a GetState needs to called to get the current state. template bool WaitForStateChange(grpc_connectivity_state last_observed, T deadline) { TimePoint deadline_tp(deadline); return WaitForStateChangeImpl(last_observed, deadline_tp.raw_time()); } /// Wait for this channel to be connected template bool WaitForConnected(T deadline) { grpc_connectivity_state state; while ((state = GetState(true)) != GRPC_CHANNEL_READY) { if (!WaitForStateChange(state, deadline)) return false; } return true; } private: template friend class ::grpc::ClientReader; template friend class ::grpc::ClientWriter; template friend class ::grpc::ClientReaderWriter; template friend class ::grpc::internal::ClientAsyncReaderFactory; template friend class ::grpc::internal::ClientAsyncWriterFactory; template friend class ::grpc::internal::ClientAsyncReaderWriterFactory; friend class ::grpc::internal::ClientAsyncResponseReaderHelper; template friend class ::grpc::internal::ClientCallbackReaderWriterFactory; template friend class ::grpc::internal::ClientCallbackReaderFactory; template friend class ::grpc::internal::ClientCallbackWriterFactory; friend class ::grpc::internal::ClientCallbackUnaryFactory; template friend class ::grpc::internal::BlockingUnaryCallImpl; template friend class ::grpc::internal::CallbackUnaryCallImpl; friend class ::grpc::internal::RpcMethod; friend class ::grpc::experimental::DelegatingChannel; friend class ::grpc::internal::InterceptedChannel; virtual internal::Call CreateCall(const internal::RpcMethod& method, ::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) = 0; virtual void PerformOpsOnCall(internal::CallOpSetInterface* ops, internal::Call* call) = 0; virtual void* RegisterMethod(const char* method) = 0; virtual void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline, ::grpc::CompletionQueue* cq, void* tag) = 0; virtual bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline) = 0; // EXPERIMENTAL // This is needed to keep codegen_test_minimal happy. InterceptedChannel needs // to make use of this but can't directly call Channel's implementation // because of the test. // Returns an empty Call object (rather than being pure) since this is a new // method and adding a new pure method to an interface would be a breaking // change (even though this is private and non-API) virtual internal::Call CreateCallInternal( const internal::RpcMethod& /*method*/, ::grpc::ClientContext* /*context*/, ::grpc::CompletionQueue* /*cq*/, size_t /*interceptor_pos*/) { return internal::Call(); } // EXPERIMENTAL // A method to get the callbackable completion queue associated with this // channel. If the return value is nullptr, this channel doesn't support // callback operations. // TODO(vjpai): Consider a better default like using a global CQ // Returns nullptr (rather than being pure) since this is a post-1.0 method // and adding a new pure method to an interface would be a breaking change // (even though this is private and non-API) virtual ::grpc::CompletionQueue* CallbackCQ() { return nullptr; } }; } // namespace grpc #endif // GRPCPP_IMPL_CODEGEN_CHANNEL_INTERFACE_H