2 // Copyright 2020 gRPC authors.
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
17 #ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CONFIG_SELECTOR_H
18 #define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CONFIG_SELECTOR_H
20 #include <grpc/support/port_platform.h>
25 #include "absl/strings/string_view.h"
27 #include <grpc/impl/codegen/grpc_types.h>
28 #include <grpc/impl/codegen/slice.h>
30 #include "src/core/ext/filters/client_channel/service_config.h"
31 #include "src/core/ext/filters/client_channel/service_config_parser.h"
32 #include "src/core/lib/gprpp/arena.h"
33 #include "src/core/lib/gprpp/ref_counted.h"
34 #include "src/core/lib/gprpp/ref_counted_ptr.h"
35 #include "src/core/lib/transport/metadata_batch.h"
37 // Channel arg key for ConfigSelector.
38 #define GRPC_ARG_CONFIG_SELECTOR "grpc.internal.config_selector"
42 // Internal API used to allow resolver implementations to override
43 // MethodConfig and provide input to LB policies on a per-call basis.
44 class ConfigSelector : public RefCounted<ConfigSelector> {
46 struct GetCallConfigArgs {
48 grpc_metadata_batch* initial_metadata;
53 // Can be set to indicate the call should be failed.
54 grpc_error* error = GRPC_ERROR_NONE;
55 // The per-method parsed configs that will be passed to
56 // ServiceConfigCallData.
57 const ServiceConfigParser::ParsedConfigVector* method_configs = nullptr;
58 // A ref to the service config that contains method_configs, held by
59 // the call to ensure that method_configs lives long enough.
60 RefCountedPtr<ServiceConfig> service_config;
61 // Call attributes that will be accessible to LB policy implementations.
62 std::map<const char*, absl::string_view> call_attributes;
63 // A callback that, if set, will be invoked when the call is
64 // committed (i.e., when we know that we will never again need to
65 // ask the picker for a subchannel for this call).
66 std::function<void()> on_call_committed;
69 virtual ~ConfigSelector() = default;
71 virtual const char* name() const = 0;
73 // Will be called only if the two objects have the same name, so
74 // subclasses can be free to safely down-cast the argument.
75 virtual bool Equals(const ConfigSelector* other) const = 0;
77 static bool Equals(const ConfigSelector* cs1, const ConfigSelector* cs2) {
78 if (cs1 == nullptr) return cs2 == nullptr;
79 if (cs2 == nullptr) return false;
80 if (strcmp(cs1->name(), cs2->name()) != 0) return false;
81 return cs1->Equals(cs2);
84 virtual CallConfig GetCallConfig(GetCallConfigArgs args) = 0;
86 grpc_arg MakeChannelArg() const;
87 static RefCountedPtr<ConfigSelector> GetFromChannelArgs(
88 const grpc_channel_args& args);
91 // Default ConfigSelector that gets the MethodConfig from the service config.
92 class DefaultConfigSelector : public ConfigSelector {
94 explicit DefaultConfigSelector(RefCountedPtr<ServiceConfig> service_config)
95 : service_config_(std::move(service_config)) {
96 // The client channel code ensures that this will never be null.
97 // If neither the resolver nor the client application provide a
98 // config, a default empty config will be used.
99 GPR_DEBUG_ASSERT(service_config_ != nullptr);
102 const char* name() const override { return "default"; }
104 // Only comparing the ConfigSelector itself, not the underlying
105 // service config, so we always return true.
106 bool Equals(const ConfigSelector* other) const override { return true; }
108 CallConfig GetCallConfig(GetCallConfigArgs args) override {
109 CallConfig call_config;
110 call_config.method_configs =
111 service_config_->GetMethodParsedConfigVector(*args.path);
112 call_config.service_config = service_config_;
117 RefCountedPtr<ServiceConfig> service_config_;
120 } // namespace grpc_core
122 #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CONFIG_SELECTOR_H */