blob: cf872afbe24c0040b4a3bbd4ddecfe700ebe79f1 [file] [log] [blame]
Mark D. Roth5e9848e2017-10-06 13:59:32 -07001/*
2 *
3 * Copyright 2015 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_LB_POLICY_SUBCHANNEL_LIST_H
20#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_SUBCHANNEL_LIST_H
21
22#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
23#include "src/core/ext/filters/client_channel/subchannel.h"
24#include "src/core/lib/transport/connectivity_state.h"
25
26// TODO(roth): This code is intended to be shared between pick_first and
27// round_robin. However, the interface needs more work to provide clean
28// encapsulation. For example, the structs here have some fields that are
29// only used in one of the two (e.g., the state counters in
30// grpc_lb_subchannel_list and the prev_connectivity_state field in
31// grpc_lb_subchannel_data are only used in round_robin, and the
32// checking_subchannel field in grpc_lb_subchannel_list is only used by
33// pick_first). Also, there is probably some code duplication between the
34// connectivity state notification callback code in both pick_first and
35// round_robin that could be refactored and moved here. In a future PR,
36// need to clean this up.
37
38#ifdef __cplusplus
39extern "C" {
40#endif
41
42typedef struct grpc_lb_subchannel_list grpc_lb_subchannel_list;
43
44typedef struct {
45 /** backpointer to owning subchannel list */
46 grpc_lb_subchannel_list *subchannel_list;
47 /** subchannel itself */
48 grpc_subchannel *subchannel;
49 grpc_connected_subchannel *connected_subchannel;
50 /** Is a connectivity notification pending? */
51 bool connectivity_notification_pending;
52 /** notification that connectivity has changed on subchannel */
53 grpc_closure connectivity_changed_closure;
54 /** previous and current connectivity states. Updated by \a
55 * \a connectivity_changed_closure based on
56 * \a pending_connectivity_state_unsafe. */
57 grpc_connectivity_state prev_connectivity_state;
58 grpc_connectivity_state curr_connectivity_state;
59 /** connectivity state to be updated by
60 * grpc_subchannel_notify_on_state_change(), not guarded by
61 * the combiner. To be copied to \a curr_connectivity_state by
62 * \a connectivity_changed_closure. */
63 grpc_connectivity_state pending_connectivity_state_unsafe;
64 /** the subchannel's target user data */
65 void *user_data;
66 /** vtable to operate over \a user_data */
67 const grpc_lb_user_data_vtable *user_data_vtable;
68} grpc_lb_subchannel_data;
69
70// Unrefs the subchannel contained in sd.
Mark D. Roth62ca6ce2017-10-10 10:01:51 -070071void grpc_lb_subchannel_data_unref_subchannel(grpc_exec_ctx *exec_ctx,
72 grpc_lb_subchannel_data *sd,
73 const char *reason);
Mark D. Roth5e9848e2017-10-06 13:59:32 -070074
75// Starts watching the connectivity state of the subchannel.
76// The connectivity_changed_cb callback must invoke either
77// grpc_lb_subchannel_data_stop_connectivity_watch() or again call
78// grpc_lb_subchannel_data_start_connectivity_watch().
79void grpc_lb_subchannel_data_start_connectivity_watch(
80 grpc_exec_ctx *exec_ctx, grpc_lb_subchannel_data *sd);
81
82// Stops watching the connectivity state of the subchannel.
83void grpc_lb_subchannel_data_stop_connectivity_watch(
84 grpc_exec_ctx *exec_ctx, grpc_lb_subchannel_data *sd);
85
86struct grpc_lb_subchannel_list {
87 /** backpointer to owning policy */
88 grpc_lb_policy *policy;
89
90 /** all our subchannels */
91 size_t num_subchannels;
92 grpc_lb_subchannel_data *subchannels;
93
94 /** Index into subchannels of the one we're currently checking.
95 * Used when connecting to subchannels serially instead of in parallel. */
96 // TODO(roth): When we have time, we can probably make this go away
97 // and the index dynamically by subtracting
98 // subchannel_list->subchannels from the subchannel_data pointer.
99 size_t checking_subchannel;
100
101 /** how many subchannels are in state READY */
102 size_t num_ready;
103 /** how many subchannels are in state TRANSIENT_FAILURE */
104 size_t num_transient_failures;
105 /** how many subchannels are in state SHUTDOWN */
106 size_t num_shutdown;
107 /** how many subchannels are in state IDLE */
108 size_t num_idle;
109
110 /** There will be one ref for each entry in subchannels for which there is a
111 * pending connectivity state watcher callback. */
112 gpr_refcount refcount;
113
114 /** Is this list shutting down? This may be true due to the shutdown of the
115 * policy itself or because a newer update has arrived while this one hadn't
116 * finished processing. */
117 bool shutting_down;
118};
119
120grpc_lb_subchannel_list *grpc_lb_subchannel_list_create(
121 grpc_exec_ctx *exec_ctx, grpc_lb_policy *p,
122 const grpc_lb_addresses *addresses, const grpc_lb_policy_args *args,
123 grpc_iomgr_cb_func connectivity_changed_cb);
124
125void grpc_lb_subchannel_list_ref(grpc_lb_subchannel_list *subchannel_list,
126 const char *reason);
127
128void grpc_lb_subchannel_list_unref(grpc_exec_ctx *exec_ctx,
129 grpc_lb_subchannel_list *subchannel_list,
130 const char *reason);
131
132// Takes and releases refs needed for a connectivity notification.
133// This includes a ref to subchannel_list and a weak ref to the LB policy.
134void grpc_lb_subchannel_list_ref_for_connectivity_watch(
135 grpc_lb_subchannel_list *subchannel_list, const char *reason);
136void grpc_lb_subchannel_list_unref_for_connectivity_watch(
137 grpc_exec_ctx *exec_ctx, grpc_lb_subchannel_list *subchannel_list,
138 const char *reason);
139
140// Mark subchannel_list as discarded. Unsubscribes all its subchannels. The
141// connectivity state notification callback will ultimately unref it.
142void grpc_lb_subchannel_list_shutdown_and_unref(
143 grpc_exec_ctx *exec_ctx, grpc_lb_subchannel_list *subchannel_list,
144 const char *reason);
145
146#ifdef __cplusplus
147}
148#endif
149
150#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_SUBCHANNEL_LIST_H */