3 * Copyright 2015 gRPC authors.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #ifndef GRPC_CORE_LIB_TRANSPORT_CONNECTIVITY_STATE_H
20 #define GRPC_CORE_LIB_TRANSPORT_CONNECTIVITY_STATE_H
22 #include <grpc/support/port_platform.h>
24 #include "absl/status/status.h"
26 #include <grpc/grpc.h>
28 #include "src/core/lib/debug/trace.h"
29 #include "src/core/lib/gprpp/atomic.h"
30 #include "src/core/lib/gprpp/map.h"
31 #include "src/core/lib/gprpp/orphanable.h"
32 #include "src/core/lib/iomgr/closure.h"
33 #include "src/core/lib/iomgr/exec_ctx.h"
34 #include "src/core/lib/iomgr/work_serializer.h"
38 extern TraceFlag grpc_connectivity_state_trace;
40 // Enum to string conversion.
41 const char* ConnectivityStateName(grpc_connectivity_state state);
43 // Interface for watching connectivity state.
44 // Subclasses must implement the Notify() method.
46 // Note: Most callers will want to use
47 // AsyncConnectivityStateWatcherInterface instead.
48 class ConnectivityStateWatcherInterface
49 : public InternallyRefCounted<ConnectivityStateWatcherInterface> {
51 virtual ~ConnectivityStateWatcherInterface() = default;
53 // Notifies the watcher that the state has changed to new_state.
54 virtual void Notify(grpc_connectivity_state new_state,
55 const absl::Status& status) = 0;
57 void Orphan() override { Unref(); }
60 // An alternative watcher interface that performs notifications via an
61 // asynchronous callback scheduled on the ExecCtx.
62 // Subclasses must implement the OnConnectivityStateChange() method.
63 class AsyncConnectivityStateWatcherInterface
64 : public ConnectivityStateWatcherInterface {
66 virtual ~AsyncConnectivityStateWatcherInterface() = default;
68 // Schedules a closure on the ExecCtx to invoke
69 // OnConnectivityStateChange() asynchronously.
70 void Notify(grpc_connectivity_state new_state,
71 const absl::Status& status) override final;
76 // If \a work_serializer is nullptr, then the notification will be scheduled
78 explicit AsyncConnectivityStateWatcherInterface(
79 std::shared_ptr<WorkSerializer> work_serializer = nullptr)
80 : work_serializer_(std::move(work_serializer)) {}
82 // Invoked asynchronously when Notify() is called.
83 virtual void OnConnectivityStateChange(grpc_connectivity_state new_state,
84 const absl::Status& status) = 0;
87 std::shared_ptr<WorkSerializer> work_serializer_;
90 // Tracks connectivity state. Maintains a list of watchers that are
91 // notified whenever the state changes.
93 // Note that once the state becomes SHUTDOWN, watchers will be notified
94 // and then automatically orphaned (i.e., RemoveWatcher() does not need
96 class ConnectivityStateTracker {
98 ConnectivityStateTracker(const char* name,
99 grpc_connectivity_state state = GRPC_CHANNEL_IDLE,
100 const absl::Status& status = absl::Status())
101 : name_(name), state_(state), status_(status) {}
103 ~ConnectivityStateTracker();
106 // If the current state is different than initial_state, the watcher
107 // will be notified immediately. Otherwise, it will be notified
108 // whenever the state changes.
109 // Not thread safe; access must be serialized with an external lock.
110 void AddWatcher(grpc_connectivity_state initial_state,
111 OrphanablePtr<ConnectivityStateWatcherInterface> watcher);
113 // Removes a watcher. The watcher will be orphaned.
114 // Not thread safe; access must be serialized with an external lock.
115 void RemoveWatcher(ConnectivityStateWatcherInterface* watcher);
117 // Sets connectivity state.
118 // Not thread safe; access must be serialized with an external lock.
119 void SetState(grpc_connectivity_state state, const absl::Status& status,
122 // Gets the current state.
123 // Thread safe; no need to use an external lock.
124 grpc_connectivity_state state() const;
126 // Get the current status.
127 // Not thread safe; access must be serialized with an external lock.
128 absl::Status status() const { return status_; }
132 Atomic<grpc_connectivity_state> state_;
133 absl::Status status_;
134 // TODO(roth): Once we can use C++-14 heterogeneous lookups, this can
135 // be a set instead of a map.
136 std::map<ConnectivityStateWatcherInterface*,
137 OrphanablePtr<ConnectivityStateWatcherInterface>>
141 } // namespace grpc_core
143 #endif /* GRPC_CORE_LIB_TRANSPORT_CONNECTIVITY_STATE_H */