diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 11890a8894f..57ac11063ee 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -441,6 +441,12 @@ class CallData { return calld_->backend_metric_data_; } + absl::string_view ExperimentalGetCallAttribute(const char* key) override { + auto it = calld_->call_attributes_.find(key); + if (it == calld_->call_attributes_.end()) return absl::string_view(); + return it->second; + } + private: CallData* calld_; }; @@ -762,6 +768,7 @@ class CallData { RefCountedPtr retry_throttle_data_; ServiceConfig::CallData service_config_call_data_; const ClientChannelMethodParsedConfig* method_params_ = nullptr; + std::map call_attributes_; RefCountedPtr subchannel_call_; diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index f76708c4e65..7a775af82f6 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -116,7 +116,17 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Returns the backend metric data returned by the server for the call, /// or null if no backend metric data was returned. + // TODO(roth): Move this out of CallState, since it should not be + // accessible to the picker, only to the recv_trailing_metadata_ready + // callback. It should instead be in its own interface. virtual const BackendMetricData* GetBackendMetricData() = 0; + + /// EXPERIMENTAL API. + /// Returns the value of the call attribute \a key. + /// Keys are static strings, so an attribute can be accessed by an LB + /// policy implementation only if it knows about the internal key. + /// Returns a null string_view if key not found. + virtual absl::string_view ExperimentalGetCallAttribute(const char* key) = 0; }; /// Interface for accessing metadata. @@ -186,7 +196,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// call to the chosen backend. MetadataInterface* initial_metadata; /// An interface for accessing call state. Can be used to allocate - /// data associated with the call in an efficient way. + /// memory associated with the call in an efficient way. CallState* call_state; }; @@ -228,6 +238,9 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// does not take ownership, so any data that needs to be used after /// returning must be copied. /// The call state can be used to obtain backend metric data. + // TODO(roth): The arguments to this callback should be moved into a + // struct, so that we can later add new fields without breaking + // existing implementations. std::function recv_trailing_metadata_ready; }; @@ -256,9 +269,6 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// A proxy object implemented by the client channel and used by the /// LB policy to communicate with the channel. - // TODO(juanlishen): Consider adding a mid-layer subclass that helps handle - // things like swapping in pending policy when it's ready. Currently, we are - // duplicating the logic in many subclasses. class ChannelControlHelper { public: ChannelControlHelper() = default;