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