|
|
|
@ -19,7 +19,8 @@ |
|
|
|
|
|
|
|
|
|
#include <grpc/support/port_platform.h> |
|
|
|
|
|
|
|
|
|
#include <new> |
|
|
|
|
#include <functional> |
|
|
|
|
#include <memory> |
|
|
|
|
#include <string> |
|
|
|
|
#include <utility> |
|
|
|
|
|
|
|
|
@ -34,10 +35,12 @@ |
|
|
|
|
#include "src/core/lib/channel/channel_fwd.h" |
|
|
|
|
#include "src/core/lib/channel/channel_stack.h" |
|
|
|
|
#include "src/core/lib/channel/channel_stack_builder.h" |
|
|
|
|
#include "src/core/lib/channel/context.h" |
|
|
|
|
#include "src/core/lib/channel/promise_based_filter.h" |
|
|
|
|
#include "src/core/lib/config/core_configuration.h" |
|
|
|
|
#include "src/core/lib/gprpp/ref_counted_ptr.h" |
|
|
|
|
#include "src/core/lib/iomgr/closure.h" |
|
|
|
|
#include "src/core/lib/iomgr/error.h" |
|
|
|
|
#include "src/core/lib/promise/arena_promise.h" |
|
|
|
|
#include "src/core/lib/promise/context.h" |
|
|
|
|
#include "src/core/lib/resource_quota/arena.h" |
|
|
|
|
#include "src/core/lib/service_config/service_config.h" |
|
|
|
|
#include "src/core/lib/service_config/service_config_call_data.h" |
|
|
|
@ -45,20 +48,25 @@ |
|
|
|
|
#include "src/core/lib/service_config/service_config_parser.h" |
|
|
|
|
#include "src/core/lib/surface/channel_init.h" |
|
|
|
|
#include "src/core/lib/surface/channel_stack_type.h" |
|
|
|
|
#include "src/core/lib/transport/metadata_batch.h" |
|
|
|
|
#include "src/core/lib/transport/transport.h" |
|
|
|
|
|
|
|
|
|
namespace grpc_core { |
|
|
|
|
|
|
|
|
|
namespace { |
|
|
|
|
|
|
|
|
|
class ServiceConfigChannelArgChannelData { |
|
|
|
|
class ServiceConfigChannelArgFilter : public ChannelFilter { |
|
|
|
|
public: |
|
|
|
|
explicit ServiceConfigChannelArgChannelData( |
|
|
|
|
const grpc_channel_element_args* args) { |
|
|
|
|
auto service_config_str = |
|
|
|
|
args->channel_args.GetOwnedString(GRPC_ARG_SERVICE_CONFIG); |
|
|
|
|
static absl::StatusOr<ServiceConfigChannelArgFilter> Create( |
|
|
|
|
const ChannelArgs& args, ChannelFilter::Args) { |
|
|
|
|
return ServiceConfigChannelArgFilter(args); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
explicit ServiceConfigChannelArgFilter(const ChannelArgs& args) { |
|
|
|
|
auto service_config_str = args.GetOwnedString(GRPC_ARG_SERVICE_CONFIG); |
|
|
|
|
if (service_config_str.has_value()) { |
|
|
|
|
auto service_config = ServiceConfigImpl::Create( |
|
|
|
|
args->channel_args, service_config_str->c_str()); |
|
|
|
|
auto service_config = |
|
|
|
|
ServiceConfigImpl::Create(args, *service_config_str); |
|
|
|
|
if (!service_config.ok()) { |
|
|
|
|
gpr_log(GPR_ERROR, "%s", service_config.status().ToString().c_str()); |
|
|
|
|
} else { |
|
|
|
@ -67,62 +75,34 @@ class ServiceConfigChannelArgChannelData { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
RefCountedPtr<ServiceConfig> service_config() const { |
|
|
|
|
return service_config_; |
|
|
|
|
} |
|
|
|
|
// Construct a promise for one call.
|
|
|
|
|
ArenaPromise<ServerMetadataHandle> MakeCallPromise( |
|
|
|
|
CallArgs call_args, NextPromiseFactory next_promise_factory) override; |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
RefCountedPtr<ServiceConfig> service_config_; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
grpc_error_handle ServiceConfigChannelArgInitCallElem( |
|
|
|
|
grpc_call_element* elem, const grpc_call_element_args* args) { |
|
|
|
|
auto* chand = |
|
|
|
|
static_cast<ServiceConfigChannelArgChannelData*>(elem->channel_data); |
|
|
|
|
RefCountedPtr<ServiceConfig> service_config = chand->service_config(); |
|
|
|
|
ArenaPromise<ServerMetadataHandle> |
|
|
|
|
ServiceConfigChannelArgFilter::MakeCallPromise( |
|
|
|
|
CallArgs call_args, NextPromiseFactory next_promise_factory) { |
|
|
|
|
const ServiceConfigParser::ParsedConfigVector* method_configs = nullptr; |
|
|
|
|
if (service_config != nullptr) { |
|
|
|
|
method_configs = service_config->GetMethodParsedConfigVector(args->path); |
|
|
|
|
if (service_config_ != nullptr) { |
|
|
|
|
method_configs = service_config_->GetMethodParsedConfigVector( |
|
|
|
|
call_args.client_initial_metadata->get_pointer(HttpPathMetadata()) |
|
|
|
|
->c_slice()); |
|
|
|
|
} |
|
|
|
|
auto* service_config_call_data = |
|
|
|
|
args->arena->New<ServiceConfigCallData>(args->arena, args->context); |
|
|
|
|
service_config_call_data->SetServiceConfig(std::move(service_config), |
|
|
|
|
method_configs); |
|
|
|
|
return absl::OkStatus(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ServiceConfigChannelArgDestroyCallElem( |
|
|
|
|
grpc_call_element* /*elem*/, const grpc_call_final_info* /*final_info*/, |
|
|
|
|
grpc_closure* /*then_schedule_closure*/) {} |
|
|
|
|
|
|
|
|
|
grpc_error_handle ServiceConfigChannelArgInitChannelElem( |
|
|
|
|
grpc_channel_element* elem, grpc_channel_element_args* args) { |
|
|
|
|
ServiceConfigChannelArgChannelData* chand = |
|
|
|
|
static_cast<ServiceConfigChannelArgChannelData*>(elem->channel_data); |
|
|
|
|
new (chand) ServiceConfigChannelArgChannelData(args); |
|
|
|
|
return absl::OkStatus(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ServiceConfigChannelArgDestroyChannelElem(grpc_channel_element* elem) { |
|
|
|
|
ServiceConfigChannelArgChannelData* chand = |
|
|
|
|
static_cast<ServiceConfigChannelArgChannelData*>(elem->channel_data); |
|
|
|
|
chand->~ServiceConfigChannelArgChannelData(); |
|
|
|
|
auto* arena = GetContext<Arena>(); |
|
|
|
|
auto* service_config_call_data = arena->New<ServiceConfigCallData>( |
|
|
|
|
arena, GetContext<grpc_call_context_element>()); |
|
|
|
|
service_config_call_data->SetServiceConfig(service_config_, method_configs); |
|
|
|
|
return next_promise_factory(std::move(call_args)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const grpc_channel_filter ServiceConfigChannelArgFilter = { |
|
|
|
|
grpc_call_next_op, |
|
|
|
|
nullptr, |
|
|
|
|
grpc_channel_next_op, |
|
|
|
|
0, |
|
|
|
|
ServiceConfigChannelArgInitCallElem, |
|
|
|
|
grpc_call_stack_ignore_set_pollset_or_pollset_set, |
|
|
|
|
ServiceConfigChannelArgDestroyCallElem, |
|
|
|
|
sizeof(ServiceConfigChannelArgChannelData), |
|
|
|
|
ServiceConfigChannelArgInitChannelElem, |
|
|
|
|
grpc_channel_stack_no_post_init, |
|
|
|
|
ServiceConfigChannelArgDestroyChannelElem, |
|
|
|
|
grpc_channel_next_get_info, |
|
|
|
|
"service_config_channel_arg"}; |
|
|
|
|
const grpc_channel_filter kServiceConfigChannelArgFilter = |
|
|
|
|
MakePromiseBasedFilter<ServiceConfigChannelArgFilter, |
|
|
|
|
FilterEndpoint::kClient>( |
|
|
|
|
"service_config_channel_arg"); |
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
@ -136,7 +116,7 @@ void RegisterServiceConfigChannelArgFilter( |
|
|
|
|
!channel_args.GetString(GRPC_ARG_SERVICE_CONFIG).has_value()) { |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
builder->PrependFilter(&ServiceConfigChannelArgFilter); |
|
|
|
|
builder->PrependFilter(&kServiceConfigChannelArgFilter); |
|
|
|
|
return true; |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|