|
|
|
@ -21,9 +21,9 @@ |
|
|
|
|
#include "src/core/lib/surface/lame_client.h" |
|
|
|
|
|
|
|
|
|
#include <memory> |
|
|
|
|
#include <new> |
|
|
|
|
#include <utility> |
|
|
|
|
|
|
|
|
|
#include "absl/memory/memory.h" |
|
|
|
|
#include "absl/status/statusor.h" |
|
|
|
|
|
|
|
|
|
#include <grpc/grpc.h> |
|
|
|
@ -33,17 +33,17 @@ |
|
|
|
|
|
|
|
|
|
#include "src/core/lib/channel/channel_args.h" |
|
|
|
|
#include "src/core/lib/channel/channel_args_preconditioning.h" |
|
|
|
|
#include "src/core/lib/channel/channel_stack.h" |
|
|
|
|
#include "src/core/lib/channel/channel_stack_builder.h" |
|
|
|
|
#include "src/core/lib/channel/promise_based_filter.h" |
|
|
|
|
#include "src/core/lib/config/core_configuration.h" |
|
|
|
|
#include "src/core/lib/debug/trace.h" |
|
|
|
|
#include "src/core/lib/gpr/useful.h" |
|
|
|
|
#include "src/core/lib/gprpp/debug_location.h" |
|
|
|
|
#include "src/core/lib/gprpp/ref_counted_ptr.h" |
|
|
|
|
#include "src/core/lib/gprpp/sync.h" |
|
|
|
|
#include "src/core/lib/iomgr/call_combiner.h" |
|
|
|
|
#include "src/core/lib/iomgr/closure.h" |
|
|
|
|
#include "src/core/lib/iomgr/exec_ctx.h" |
|
|
|
|
#include "src/core/lib/promise/poll.h" |
|
|
|
|
#include "src/core/lib/promise/promise.h" |
|
|
|
|
#include "src/core/lib/surface/api_trace.h" |
|
|
|
|
#include "src/core/lib/surface/channel.h" |
|
|
|
|
#include "src/core/lib/surface/channel_stack_type.h" |
|
|
|
@ -57,49 +57,38 @@ |
|
|
|
|
|
|
|
|
|
namespace grpc_core { |
|
|
|
|
|
|
|
|
|
namespace { |
|
|
|
|
|
|
|
|
|
struct ChannelData { |
|
|
|
|
explicit ChannelData(grpc_channel_element_args* args) |
|
|
|
|
: state_tracker("lame_channel", GRPC_CHANNEL_SHUTDOWN) { |
|
|
|
|
grpc_error_handle* err = grpc_channel_args_find_pointer<grpc_error_handle>( |
|
|
|
|
args->channel_args, GRPC_ARG_LAME_FILTER_ERROR); |
|
|
|
|
if (err != nullptr) error = GRPC_ERROR_REF(*err); |
|
|
|
|
} |
|
|
|
|
const grpc_channel_filter LameClientFilter::kFilter = |
|
|
|
|
MakePromiseBasedFilter<LameClientFilter, FilterEndpoint::kClient, |
|
|
|
|
kFilterIsLast>("lame-client"); |
|
|
|
|
|
|
|
|
|
~ChannelData() { GRPC_ERROR_UNREF(error); } |
|
|
|
|
absl::StatusOr<LameClientFilter> LameClientFilter::Create(ChannelArgs args, |
|
|
|
|
ChannelFilter::Args) { |
|
|
|
|
return LameClientFilter( |
|
|
|
|
*args.GetPointer<absl::Status>(GRPC_ARG_LAME_FILTER_ERROR)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
grpc_error_handle error = GRPC_ERROR_NONE; |
|
|
|
|
Mutex mu; |
|
|
|
|
ConnectivityStateTracker state_tracker; |
|
|
|
|
}; |
|
|
|
|
LameClientFilter::LameClientFilter(absl::Status error) |
|
|
|
|
: error_(std::move(error)), state_(absl::make_unique<State>()) {} |
|
|
|
|
|
|
|
|
|
struct CallData { |
|
|
|
|
CallCombiner* call_combiner; |
|
|
|
|
}; |
|
|
|
|
LameClientFilter::State::State() |
|
|
|
|
: state_tracker("lame_client", GRPC_CHANNEL_SHUTDOWN) {} |
|
|
|
|
|
|
|
|
|
void lame_start_transport_stream_op_batch(grpc_call_element* elem, |
|
|
|
|
grpc_transport_stream_op_batch* op) { |
|
|
|
|
CallData* calld = static_cast<CallData*>(elem->call_data); |
|
|
|
|
ChannelData* chand = static_cast<ChannelData*>(elem->channel_data); |
|
|
|
|
grpc_transport_stream_op_batch_finish_with_failure( |
|
|
|
|
op, GRPC_ERROR_REF(chand->error), calld->call_combiner); |
|
|
|
|
ArenaPromise<ServerMetadataHandle> LameClientFilter::MakeCallPromise( |
|
|
|
|
CallArgs, NextPromiseFactory) { |
|
|
|
|
return Immediate(ServerMetadataHandle(error_)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void lame_get_channel_info(grpc_channel_element* /*elem*/, |
|
|
|
|
const grpc_channel_info* /*channel_info*/) {} |
|
|
|
|
bool LameClientFilter::GetChannelInfo(const grpc_channel_info*) { return true; } |
|
|
|
|
|
|
|
|
|
void lame_start_transport_op(grpc_channel_element* elem, |
|
|
|
|
grpc_transport_op* op) { |
|
|
|
|
ChannelData* chand = static_cast<ChannelData*>(elem->channel_data); |
|
|
|
|
bool LameClientFilter::StartTransportOp(grpc_transport_op* op) { |
|
|
|
|
{ |
|
|
|
|
MutexLock lock(&chand->mu); |
|
|
|
|
MutexLock lock(&state_->mu); |
|
|
|
|
if (op->start_connectivity_watch != nullptr) { |
|
|
|
|
chand->state_tracker.AddWatcher(op->start_connectivity_watch_state, |
|
|
|
|
std::move(op->start_connectivity_watch)); |
|
|
|
|
state_->state_tracker.AddWatcher(op->start_connectivity_watch_state, |
|
|
|
|
std::move(op->start_connectivity_watch)); |
|
|
|
|
} |
|
|
|
|
if (op->stop_connectivity_watch != nullptr) { |
|
|
|
|
chand->state_tracker.RemoveWatcher(op->stop_connectivity_watch); |
|
|
|
|
state_->state_tracker.RemoveWatcher(op->stop_connectivity_watch); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (op->send_ping.on_initiate != nullptr) { |
|
|
|
@ -114,50 +103,18 @@ void lame_start_transport_op(grpc_channel_element* elem, |
|
|
|
|
if (op->on_consumed != nullptr) { |
|
|
|
|
ExecCtx::Run(DEBUG_LOCATION, op->on_consumed, GRPC_ERROR_NONE); |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
grpc_error_handle lame_init_call_elem(grpc_call_element* elem, |
|
|
|
|
const grpc_call_element_args* args) { |
|
|
|
|
CallData* calld = static_cast<CallData*>(elem->call_data); |
|
|
|
|
calld->call_combiner = args->call_combiner; |
|
|
|
|
return GRPC_ERROR_NONE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void lame_destroy_call_elem(grpc_call_element* /*elem*/, |
|
|
|
|
const grpc_call_final_info* /*final_info*/, |
|
|
|
|
grpc_closure* then_schedule_closure) { |
|
|
|
|
ExecCtx::Run(DEBUG_LOCATION, then_schedule_closure, GRPC_ERROR_NONE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
grpc_error_handle lame_init_channel_elem(grpc_channel_element* elem, |
|
|
|
|
grpc_channel_element_args* args) { |
|
|
|
|
new (elem->channel_data) ChannelData(args); |
|
|
|
|
return GRPC_ERROR_NONE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void lame_destroy_channel_elem(grpc_channel_element* elem) { |
|
|
|
|
ChannelData* chand = static_cast<ChannelData*>(elem->channel_data); |
|
|
|
|
chand->~ChannelData(); |
|
|
|
|
} |
|
|
|
|
namespace { |
|
|
|
|
|
|
|
|
|
// Channel arg vtable for a grpc_error_handle.
|
|
|
|
|
void* ErrorCopy(void* p) { |
|
|
|
|
grpc_error_handle* new_error = nullptr; |
|
|
|
|
if (p != nullptr) { |
|
|
|
|
grpc_error_handle* error = static_cast<grpc_error_handle*>(p); |
|
|
|
|
new_error = new grpc_error_handle(); |
|
|
|
|
*new_error = GRPC_ERROR_REF(*error); |
|
|
|
|
} |
|
|
|
|
return new_error; |
|
|
|
|
} |
|
|
|
|
void ErrorDestroy(void* p) { |
|
|
|
|
if (p != nullptr) { |
|
|
|
|
grpc_error_handle* error = static_cast<grpc_error_handle*>(p); |
|
|
|
|
GRPC_ERROR_UNREF(*error); |
|
|
|
|
delete error; |
|
|
|
|
} |
|
|
|
|
return new absl::Status(*static_cast<absl::Status*>(p)); |
|
|
|
|
} |
|
|
|
|
void ErrorDestroy(void* p) { delete static_cast<absl::Status*>(p); } |
|
|
|
|
int ErrorCompare(void* p, void* q) { return QsortCompare(p, q); } |
|
|
|
|
|
|
|
|
|
const grpc_arg_pointer_vtable kLameFilterErrorArgVtable = { |
|
|
|
|
ErrorCopy, ErrorDestroy, ErrorCompare}; |
|
|
|
|
|
|
|
|
@ -171,24 +128,6 @@ grpc_arg MakeLameClientErrorArg(grpc_error_handle* error) { |
|
|
|
|
|
|
|
|
|
} // namespace grpc_core
|
|
|
|
|
|
|
|
|
|
const grpc_channel_filter grpc_lame_filter = { |
|
|
|
|
grpc_core::lame_start_transport_stream_op_batch, |
|
|
|
|
nullptr, |
|
|
|
|
grpc_core::lame_start_transport_op, |
|
|
|
|
sizeof(grpc_core::CallData), |
|
|
|
|
grpc_core::lame_init_call_elem, |
|
|
|
|
grpc_call_stack_ignore_set_pollset_or_pollset_set, |
|
|
|
|
grpc_core::lame_destroy_call_elem, |
|
|
|
|
sizeof(grpc_core::ChannelData), |
|
|
|
|
grpc_core::lame_init_channel_elem, |
|
|
|
|
grpc_channel_stack_no_post_init, |
|
|
|
|
grpc_core::lame_destroy_channel_elem, |
|
|
|
|
grpc_core::lame_get_channel_info, |
|
|
|
|
"lame-client", |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
#define CHANNEL_STACK_FROM_CHANNEL(c) ((grpc_channel_stack*)((c) + 1)) |
|
|
|
|
|
|
|
|
|
grpc_channel* grpc_lame_client_channel_create(const char* target, |
|
|
|
|
grpc_status_code error_code, |
|
|
|
|
const char* error_message) { |
|
|
|
@ -197,18 +136,15 @@ grpc_channel* grpc_lame_client_channel_create(const char* target, |
|
|
|
|
"grpc_lame_client_channel_create(target=%s, error_code=%d, " |
|
|
|
|
"error_message=%s)", |
|
|
|
|
3, (target, (int)error_code, error_message)); |
|
|
|
|
grpc_error_handle error = grpc_error_set_str( |
|
|
|
|
grpc_error_set_int( |
|
|
|
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("lame client channel"), |
|
|
|
|
GRPC_ERROR_INT_GRPC_STATUS, error_code), |
|
|
|
|
GRPC_ERROR_STR_GRPC_MESSAGE, error_message); |
|
|
|
|
if (error_code == GRPC_STATUS_OK) error_code = GRPC_STATUS_UNKNOWN; |
|
|
|
|
grpc_core::ChannelArgs args = |
|
|
|
|
grpc_core::CoreConfiguration::Get() |
|
|
|
|
.channel_args_preconditioning() |
|
|
|
|
.PreconditionChannelArgs(nullptr) |
|
|
|
|
.Set(GRPC_ARG_LAME_FILTER_ERROR, |
|
|
|
|
grpc_core::ChannelArgs::Pointer( |
|
|
|
|
new grpc_error_handle(error), |
|
|
|
|
new absl::Status(static_cast<absl::StatusCode>(error_code), |
|
|
|
|
error_message), |
|
|
|
|
&grpc_core::kLameFilterErrorArgVtable)); |
|
|
|
|
auto channel = grpc_core::Channel::Create(target, std::move(args), |
|
|
|
|
GRPC_CLIENT_LAME_CHANNEL, nullptr); |
|
|
|
|