| /* |
| * |
| * Copyright 2018 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 GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_REQUEST_ROUTING_H |
| #define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_REQUEST_ROUTING_H |
| |
| #include <grpc/support/port_platform.h> |
| |
| #include "src/core/ext/filters/client_channel/client_channel_channelz.h" |
| #include "src/core/ext/filters/client_channel/client_channel_factory.h" |
| #include "src/core/ext/filters/client_channel/lb_policy.h" |
| #include "src/core/ext/filters/client_channel/resolver.h" |
| #include "src/core/lib/channel/channel_args.h" |
| #include "src/core/lib/channel/channel_stack.h" |
| #include "src/core/lib/debug/trace.h" |
| #include "src/core/lib/gprpp/inlined_vector.h" |
| #include "src/core/lib/gprpp/orphanable.h" |
| #include "src/core/lib/iomgr/call_combiner.h" |
| #include "src/core/lib/iomgr/closure.h" |
| #include "src/core/lib/iomgr/polling_entity.h" |
| #include "src/core/lib/iomgr/pollset_set.h" |
| #include "src/core/lib/transport/connectivity_state.h" |
| #include "src/core/lib/transport/metadata_batch.h" |
| |
| namespace grpc_core { |
| |
| class RequestRouter { |
| public: |
| class Request { |
| public: |
| // Synchronous callback that applies the service config to a call. |
| // Returns false if the call should be failed. |
| typedef bool (*ApplyServiceConfigCallback)(void* user_data); |
| |
| Request(grpc_call_stack* owning_call, grpc_call_combiner* call_combiner, |
| grpc_polling_entity* pollent, |
| grpc_metadata_batch* send_initial_metadata, |
| uint32_t* send_initial_metadata_flags, |
| ApplyServiceConfigCallback apply_service_config, |
| void* apply_service_config_user_data, grpc_closure* on_route_done); |
| |
| ~Request(); |
| |
| // TODO(roth): It seems a bit ugly to expose this member in a |
| // non-const way. Find a better API to avoid this. |
| LoadBalancingPolicy::PickState* pick() { return &pick_; } |
| |
| private: |
| friend class RequestRouter; |
| |
| class ResolverResultWaiter; |
| class AsyncPickCanceller; |
| |
| void ProcessServiceConfigAndStartLbPickLocked(); |
| void StartLbPickLocked(); |
| static void LbPickDoneLocked(void* arg, grpc_error* error); |
| |
| void MaybeAddCallToInterestedPartiesLocked(); |
| void MaybeRemoveCallFromInterestedPartiesLocked(); |
| |
| // Populated by caller. |
| grpc_call_stack* owning_call_; |
| grpc_call_combiner* call_combiner_; |
| grpc_polling_entity* pollent_; |
| ApplyServiceConfigCallback apply_service_config_; |
| void* apply_service_config_user_data_; |
| grpc_closure* on_route_done_; |
| LoadBalancingPolicy::PickState pick_; |
| |
| // Internal state. |
| RequestRouter* request_router_ = nullptr; |
| bool pollent_added_to_interested_parties_ = false; |
| grpc_closure on_pick_done_; |
| AsyncPickCanceller* pick_canceller_ = nullptr; |
| }; |
| |
| // Synchronous callback that takes the service config JSON string and |
| // LB policy name. |
| // Returns true if the service config has changed since the last result. |
| typedef bool (*ProcessResolverResultCallback)(void* user_data, |
| const grpc_channel_args& args, |
| const char** lb_policy_name, |
| grpc_json** lb_policy_config); |
| |
| RequestRouter(grpc_channel_stack* owning_stack, grpc_combiner* combiner, |
| grpc_client_channel_factory* client_channel_factory, |
| grpc_pollset_set* interested_parties, TraceFlag* tracer, |
| ProcessResolverResultCallback process_resolver_result, |
| void* process_resolver_result_user_data, const char* target_uri, |
| const grpc_channel_args* args, grpc_error** error); |
| |
| ~RequestRouter(); |
| |
| void set_channelz_node(channelz::ClientChannelNode* channelz_node) { |
| channelz_node_ = channelz_node; |
| } |
| |
| void RouteCallLocked(Request* request); |
| |
| // TODO(roth): Add methods to cancel picks. |
| |
| void ShutdownLocked(grpc_error* error); |
| |
| void ExitIdleLocked(); |
| void ResetConnectionBackoffLocked(); |
| |
| grpc_connectivity_state GetConnectivityState(); |
| void NotifyOnConnectivityStateChange(grpc_connectivity_state* state, |
| grpc_closure* closure); |
| |
| LoadBalancingPolicy* lb_policy() const { return lb_policy_.get(); } |
| |
| private: |
| using TraceStringVector = grpc_core::InlinedVector<char*, 3>; |
| |
| class ReresolutionRequestHandler; |
| class LbConnectivityWatcher; |
| |
| void StartResolvingLocked(); |
| void OnResolverShutdownLocked(grpc_error* error); |
| void CreateNewLbPolicyLocked(const char* lb_policy_name, grpc_json* lb_config, |
| grpc_connectivity_state* connectivity_state, |
| grpc_error** connectivity_error, |
| TraceStringVector* trace_strings); |
| void MaybeAddTraceMessagesForAddressChangesLocked( |
| TraceStringVector* trace_strings); |
| void ConcatenateAndAddChannelTraceLocked( |
| TraceStringVector* trace_strings) const; |
| static void OnResolverResultChangedLocked(void* arg, grpc_error* error); |
| |
| void SetConnectivityStateLocked(grpc_connectivity_state state, |
| grpc_error* error, const char* reason); |
| |
| // Passed in from caller at construction time. |
| grpc_channel_stack* owning_stack_; |
| grpc_combiner* combiner_; |
| grpc_client_channel_factory* client_channel_factory_; |
| grpc_pollset_set* interested_parties_; |
| TraceFlag* tracer_; |
| |
| channelz::ClientChannelNode* channelz_node_ = nullptr; |
| |
| // Resolver and associated state. |
| OrphanablePtr<Resolver> resolver_; |
| ProcessResolverResultCallback process_resolver_result_; |
| void* process_resolver_result_user_data_; |
| bool started_resolving_ = false; |
| grpc_channel_args* resolver_result_ = nullptr; |
| bool previous_resolution_contained_addresses_ = false; |
| grpc_closure_list waiting_for_resolver_result_closures_; |
| grpc_closure on_resolver_result_changed_; |
| |
| // LB policy and associated state. |
| OrphanablePtr<LoadBalancingPolicy> lb_policy_; |
| bool exit_idle_when_lb_policy_arrives_ = false; |
| |
| grpc_connectivity_state_tracker state_tracker_; |
| }; |
| |
| } // namespace grpc_core |
| |
| #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_REQUEST_ROUTING_H */ |