1 /*
2  *
3  * Copyright 2019 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 GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_INTERFACE_H
20 #define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_INTERFACE_H
21 
22 #include <grpc/support/port_platform.h>
23 
24 #include <grpc/impl/codegen/connectivity_state.h>
25 #include <grpc/impl/codegen/grpc_types.h>
26 
27 #include "src/core/lib/gprpp/ref_counted.h"
28 #include "src/core/lib/iomgr/pollset_set.h"
29 
30 namespace grpc_core {
31 
32 // The interface for subchannels that is exposed to LB policy implementations.
33 class SubchannelInterface : public RefCounted<SubchannelInterface> {
34  public:
35   class ConnectivityStateWatcherInterface {
36    public:
37     virtual ~ConnectivityStateWatcherInterface() = default;
38 
39     // Will be invoked whenever the subchannel's connectivity state
40     // changes.  There will be only one invocation of this method on a
41     // given watcher instance at any given time.
42     virtual void OnConnectivityStateChange(
43         grpc_connectivity_state new_state) = 0;
44 
45     // TODO(roth): Remove this as soon as we move to EventManager-based
46     // polling.
47     virtual grpc_pollset_set* interested_parties() = 0;
48   };
49 
50   explicit SubchannelInterface(const char* trace = nullptr)
51       : RefCounted<SubchannelInterface>(trace) {}
52 
53   ~SubchannelInterface() override = default;
54 
55   // Returns the current connectivity state of the subchannel.
56   virtual grpc_connectivity_state CheckConnectivityState() = 0;
57 
58   // Starts watching the subchannel's connectivity state.
59   // The first callback to the watcher will be delivered when the
60   // subchannel's connectivity state becomes a value other than
61   // initial_state, which may happen immediately.
62   // Subsequent callbacks will be delivered as the subchannel's state
63   // changes.
64   // The watcher will be destroyed either when the subchannel is
65   // destroyed or when CancelConnectivityStateWatch() is called.
66   // There can be only one watcher of a given subchannel.  It is not
67   // valid to call this method a second time without first cancelling
68   // the previous watcher using CancelConnectivityStateWatch().
69   virtual void WatchConnectivityState(
70       grpc_connectivity_state initial_state,
71       std::unique_ptr<ConnectivityStateWatcherInterface> watcher) = 0;
72 
73   // Cancels a connectivity state watch.
74   // If the watcher has already been destroyed, this is a no-op.
75   virtual void CancelConnectivityStateWatch(
76       ConnectivityStateWatcherInterface* watcher) = 0;
77 
78   // Attempt to connect to the backend.  Has no effect if already connected.
79   // If the subchannel is currently in backoff delay due to a previously
80   // failed attempt, the new connection attempt will not start until the
81   // backoff delay has elapsed.
82   virtual void AttemptToConnect() = 0;
83 
84   // Resets the subchannel's connection backoff state.  If AttemptToConnect()
85   // has been called since the subchannel entered TRANSIENT_FAILURE state,
86   // starts a new connection attempt immediately; otherwise, a new connection
87   // attempt will be started as soon as AttemptToConnect() is called.
88   virtual void ResetBackoff() = 0;
89 
90   // TODO(roth): Need a better non-grpc-specific abstraction here.
91   virtual const grpc_channel_args* channel_args() = 0;
92 };
93 
94 // A class that delegates to another subchannel, to be used in cases
95 // where an LB policy needs to wrap a subchannel.
96 class DelegatingSubchannel : public SubchannelInterface {
97  public:
DelegatingSubchannel(RefCountedPtr<SubchannelInterface> subchannel)98   explicit DelegatingSubchannel(RefCountedPtr<SubchannelInterface> subchannel)
99       : wrapped_subchannel_(std::move(subchannel)) {}
100 
wrapped_subchannel()101   RefCountedPtr<SubchannelInterface> wrapped_subchannel() const {
102     return wrapped_subchannel_;
103   }
104 
CheckConnectivityState()105   grpc_connectivity_state CheckConnectivityState() override {
106     return wrapped_subchannel_->CheckConnectivityState();
107   }
WatchConnectivityState(grpc_connectivity_state initial_state,std::unique_ptr<ConnectivityStateWatcherInterface> watcher)108   void WatchConnectivityState(
109       grpc_connectivity_state initial_state,
110       std::unique_ptr<ConnectivityStateWatcherInterface> watcher) override {
111     return wrapped_subchannel_->WatchConnectivityState(initial_state,
112                                                        std::move(watcher));
113   }
CancelConnectivityStateWatch(ConnectivityStateWatcherInterface * watcher)114   void CancelConnectivityStateWatch(
115       ConnectivityStateWatcherInterface* watcher) override {
116     return wrapped_subchannel_->CancelConnectivityStateWatch(watcher);
117   }
AttemptToConnect()118   void AttemptToConnect() override { wrapped_subchannel_->AttemptToConnect(); }
ResetBackoff()119   void ResetBackoff() override { wrapped_subchannel_->ResetBackoff(); }
channel_args()120   const grpc_channel_args* channel_args() override {
121     return wrapped_subchannel_->channel_args();
122   }
123 
124  private:
125   RefCountedPtr<SubchannelInterface> wrapped_subchannel_;
126 };
127 
128 }  // namespace grpc_core
129 
130 #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_INTERFACE_H */
131