Skip to content

Commit 2d40a37

Browse files
tanvi-jagtapcopybara-github
authored andcommitted
[PH2][ChannelZ][ZTrace][Skeleton]
What this does : 1. Basic skeleton for ChannelZ stuff in Http2ClientTransport 2. Basic plumbing for the channel args to enable ChannelZ in Http2ClientTransport tests, end to end tests and Connector code What this does not do : 1. Exhaustive list of everything that we want to trace. A lot needs to be done here. But we will gradually build this as we debug. We will organically build this. 2. Some of the tests will not include this stuff in the post mortems. We will look at that too. PiperOrigin-RevId: 812651089
1 parent 83acb27 commit 2d40a37

File tree

8 files changed

+162
-37
lines changed

8 files changed

+162
-37
lines changed

src/core/ext/transport/chttp2/transport/http2_client_transport.cc

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "src/core/ext/transport/chttp2/transport/http2_settings.h"
4040
#include "src/core/ext/transport/chttp2/transport/http2_settings_manager.h"
4141
#include "src/core/ext/transport/chttp2/transport/http2_status.h"
42+
#include "src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h"
4243
#include "src/core/ext/transport/chttp2/transport/internal_channel_arg_names.h"
4344
#include "src/core/ext/transport/chttp2/transport/message_assembler.h"
4445
#include "src/core/ext/transport/chttp2/transport/stream_data_queue.h"
@@ -699,7 +700,11 @@ auto Http2ClientTransport::WriteControlFrames() {
699700
return self->endpoint_.Write(std::move(output_buf),
700701
PromiseEndpoint::WriteArgs{});
701702
},
702-
[] { return absl::OkStatus(); });
703+
[self = RefAsSubclass<Http2ClientTransport>(), buffer_length] {
704+
self->ztrace_collector_->Append(
705+
PromiseEndpointWriteTrace{buffer_length});
706+
return absl::OkStatus();
707+
});
703708
}
704709

705710
void Http2ClientTransport::NotifyControlFramesWriteDone() {
@@ -908,7 +913,9 @@ Http2ClientTransport::Http2ClientTransport(
908913
PromiseEndpoint endpoint, GRPC_UNUSED const ChannelArgs& channel_args,
909914
std::shared_ptr<EventEngine> event_engine,
910915
grpc_closure* on_receive_settings)
911-
: endpoint_(std::move(endpoint)),
916+
: channelz::DataSource(http2::CreateChannelzSocketNode(
917+
endpoint.GetEventEngineEndpoint(), channel_args)),
918+
endpoint_(std::move(endpoint)),
912919
stream_id_mutex_(/*Initial Stream Id*/ 1),
913920
should_reset_ping_clock_(false),
914921
incoming_header_in_progress_(false),
@@ -959,8 +966,10 @@ Http2ClientTransport::Http2ClientTransport(
959966
flow_control_(
960967
"PH2_Client",
961968
channel_args.GetBool(GRPC_ARG_HTTP2_BDP_PROBE).value_or(true),
962-
&memory_owner_) {
969+
&memory_owner_),
970+
ztrace_collector_(std::make_shared<PromiseHttp2ZTraceCollector>()) {
963971
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Constructor Begin";
972+
SourceConstructed();
964973

965974
InitLocalSettings(settings_.mutable_local(), /*is_client=*/true);
966975
ReadSettingsFromChannelArgs(channel_args, settings_.mutable_local(),
@@ -1190,9 +1199,24 @@ Http2ClientTransport::~Http2ClientTransport() {
11901199
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Destructor Begin";
11911200
GRPC_DCHECK(stream_list_.empty());
11921201
memory_owner_.Reset();
1202+
SourceDestructing();
11931203
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Destructor End";
11941204
}
11951205

1206+
void Http2ClientTransport::AddData(channelz::DataSink sink) {
1207+
sink.AddData(
1208+
"Http2ClientTransport",
1209+
channelz::PropertyList()
1210+
.Set("settings", settings_.ChannelzProperties())
1211+
.Set("keepalive_time", keepalive_time_)
1212+
.Set("keepalive_timeout", keepalive_timeout_)
1213+
.Set("ping_timeout", ping_timeout_)
1214+
.Set("keepalive_permit_without_calls",
1215+
keepalive_permit_without_calls_)
1216+
.Set("flow_control", flow_control_.stats().ChannelzProperties()));
1217+
general_party_->ExportToChannelz("Http2ClientTransport Party", sink);
1218+
}
1219+
11961220
///////////////////////////////////////////////////////////////////////////////
11971221
// Stream Related Operations
11981222

src/core/ext/transport/chttp2/transport/http2_client_transport.h

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "src/core/ext/transport/chttp2/transport/http2_settings_promises.h"
3636
#include "src/core/ext/transport/chttp2/transport/http2_status.h"
3737
#include "src/core/ext/transport/chttp2/transport/http2_transport.h"
38+
#include "src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h"
3839
#include "src/core/ext/transport/chttp2/transport/keepalive.h"
3940
#include "src/core/ext/transport/chttp2/transport/message_assembler.h"
4041
#include "src/core/ext/transport/chttp2/transport/ping_promise.h"
@@ -90,7 +91,8 @@ namespace http2 {
9091
// familiar with the PH2 project (Moving chttp2 to promises.)
9192
// TODO(tjagtap) : [PH2][P3] : Update the experimental status of the code before
9293
// http2 rollout begins.
93-
class Http2ClientTransport final : public ClientTransport {
94+
class Http2ClientTransport final : public ClientTransport,
95+
public channelz::DataSource {
9496
// TODO(tjagtap) : [PH2][P3] Move the definitions to the header for better
9597
// inlining. For now definitions are in the cc file to
9698
// reduce cognitive load in the header.
@@ -130,9 +132,18 @@ class Http2ClientTransport final : public ClientTransport {
130132
void AbortWithError();
131133

132134
RefCountedPtr<channelz::SocketNode> GetSocketNode() const override {
135+
return const_cast<channelz::BaseNode*>(
136+
channelz::DataSource::channelz_node())
137+
->RefAsSubclass<channelz::SocketNode>();
138+
}
139+
140+
std::unique_ptr<channelz::ZTrace> GetZTrace(absl::string_view name) override {
141+
if (name == "transport_frames") return ztrace_collector_->MakeZTrace();
133142
return nullptr;
134143
}
135144

145+
void AddData(channelz::DataSink sink) override;
146+
136147
auto TestOnlyTriggerWriteCycle() {
137148
return Immediate(writable_stream_list_.ForceReadyForWrite());
138149
}
@@ -311,15 +322,13 @@ class Http2ClientTransport final : public ClientTransport {
311322

312323
auto EndpointReadSlice(const size_t num_bytes) {
313324
return Map(endpoint_.ReadSlice(num_bytes),
314-
[self = RefAsSubclass<Http2ClientTransport>()](
315-
absl::StatusOr<Slice> status) {
316-
// We are ignoring the case where the read fails and call
317-
// GotData() regardless. Reasoning:
318-
// 1. It is expected that if the read fails, the transport will
319-
// close and the keepalive loop will be stopped.
320-
// 2. It does not seem worth to have an extra condition for the
321-
// success cases which would be way more common.
322-
self->keepalive_manager_.GotData();
325+
[self = RefAsSubclass<Http2ClientTransport>(),
326+
num_bytes](absl::StatusOr<Slice> status) {
327+
if (status.ok()) {
328+
self->keepalive_manager_.GotData();
329+
self->ztrace_collector_->Append(
330+
PromiseEndpointReadTrace{num_bytes});
331+
}
323332
return status;
324333
});
325334
}
@@ -351,15 +360,13 @@ class Http2ClientTransport final : public ClientTransport {
351360

352361
auto EndpointRead(const size_t num_bytes) {
353362
return Map(endpoint_.Read(num_bytes),
354-
[self = RefAsSubclass<Http2ClientTransport>()](
355-
absl::StatusOr<SliceBuffer> status) {
356-
// We are ignoring the case where the read fails and call
357-
// GotData() regardless. Reasoning:
358-
// 1. It is expected that if the read fails, the transport will
359-
// close and the keepalive loop will be stopped.
360-
// 2. It does not seem worth to have an extra condition for the
361-
// success cases which would be way more common.
362-
self->keepalive_manager_.GotData();
363+
[self = RefAsSubclass<Http2ClientTransport>(),
364+
num_bytes](absl::StatusOr<SliceBuffer> status) {
365+
if (status.ok()) {
366+
self->keepalive_manager_.GotData();
367+
self->ztrace_collector_->Append(
368+
PromiseEndpointReadTrace{num_bytes});
369+
}
363370
return status;
364371
});
365372
}
@@ -611,6 +618,7 @@ class Http2ClientTransport final : public ClientTransport {
611618
GRPC_UNUSED bool enable_preferred_rx_crypto_frame_advertisement_;
612619
MemoryOwner memory_owner_;
613620
chttp2::TransportFlowControl flow_control_;
621+
std::shared_ptr<PromiseHttp2ZTraceCollector> ztrace_collector_;
614622
};
615623

616624
// Since the corresponding class in CHTTP2 is about 3.9KB, our goal is to

src/core/ext/transport/chttp2/transport/http2_transport.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include "src/core/call/call_spine.h"
2525
#include "src/core/call/metadata_info.h"
26+
#include "src/core/channelz/channelz.h"
2627
#include "src/core/ext/transport/chttp2/transport/flow_control.h"
2728
#include "src/core/ext/transport/chttp2/transport/frame.h"
2829
#include "src/core/lib/promise/mpsc.h"
@@ -123,5 +124,26 @@ void ReadSettingsFromChannelArgs(const ChannelArgs& channel_args,
123124
<< "}";
124125
}
125126

127+
RefCountedPtr<channelz::SocketNode> CreateChannelzSocketNode(
128+
std::shared_ptr<grpc_event_engine::experimental::EventEngine::Endpoint>
129+
event_engine_endpoint,
130+
const ChannelArgs& args) {
131+
if (args.GetBool(GRPC_ARG_ENABLE_CHANNELZ)
132+
.value_or(GRPC_ENABLE_CHANNELZ_DEFAULT)) {
133+
auto local_addr = grpc_event_engine::experimental::ResolvedAddressToString(
134+
event_engine_endpoint->GetLocalAddress());
135+
auto peer_addr = grpc_event_engine::experimental::ResolvedAddressToString(
136+
event_engine_endpoint->GetPeerAddress());
137+
GRPC_HTTP2_COMMON_DLOG << "CreateChannelzSocketNode: local_addr: "
138+
<< local_addr.value_or("unknown")
139+
<< " peer_addr: " << peer_addr.value_or("unknown");
140+
return MakeRefCounted<channelz::SocketNode>(
141+
local_addr.value_or("unknown"), peer_addr.value_or("unknown"),
142+
absl::StrCat("http2", " ", peer_addr.value_or("unknown")),
143+
args.GetObjectRef<channelz::SocketNode::Security>());
144+
}
145+
return nullptr;
146+
}
147+
126148
} // namespace http2
127149
} // namespace grpc_core

src/core/ext/transport/chttp2/transport/http2_transport.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@
2424

2525
#include "src/core/call/call_spine.h"
2626
#include "src/core/call/metadata_info.h"
27+
#include "src/core/channelz/channelz.h"
2728
#include "src/core/ext/transport/chttp2/transport/flow_control.h"
2829
#include "src/core/ext/transport/chttp2/transport/frame.h"
2930
#include "src/core/ext/transport/chttp2/transport/http2_settings.h"
31+
#include "src/core/lib/event_engine/tcp_socket_utils.h"
3032
#include "src/core/lib/promise/mpsc.h"
3133
#include "src/core/lib/promise/party.h"
3234
#include "src/core/lib/transport/promise_endpoint.h"
@@ -70,6 +72,11 @@ void ReadSettingsFromChannelArgs(const ChannelArgs& channel_args,
7072
chttp2::TransportFlowControl& flow_control,
7173
const bool is_client);
7274

75+
RefCountedPtr<channelz::SocketNode> CreateChannelzSocketNode(
76+
std::shared_ptr<grpc_event_engine::experimental::EventEngine::Endpoint>
77+
event_engine_endpoint,
78+
const ChannelArgs& args);
79+
7380
} // namespace http2
7481
} // namespace grpc_core
7582

src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <map>
2020
#include <string>
2121

22+
#include "src/core/channelz/property_list.h"
2223
#include "src/core/channelz/ztrace_collector.h"
2324
#include "src/core/ext/transport/chttp2/transport/frame.h"
2425

@@ -230,6 +231,37 @@ using Http2ZTraceCollector = channelz::ZTraceCollector<
230231
H2UnknownFrameTrace, H2FlowControlStall, H2BeginWriteCycle, H2EndWriteCycle,
231232
H2BeginEndpointWrite>;
232233

234+
struct PromiseEndpointReadTrace {
235+
uint64_t bytes;
236+
channelz::PropertyList ChannelzProperties() const {
237+
return channelz::PropertyList().Set("read_bytes", bytes);
238+
}
239+
};
240+
241+
struct PromiseEndpointWriteTrace {
242+
uint64_t bytes;
243+
channelz::PropertyList ChannelzProperties() const {
244+
return channelz::PropertyList().Set("written_bytes", bytes);
245+
}
246+
};
247+
248+
namespace promise_http2_ztrace_collector_detail {
249+
class Config {
250+
public:
251+
explicit Config(const channelz::ZTrace::Args&) {}
252+
253+
template <typename T>
254+
bool Finishes(const T&) {
255+
return false;
256+
}
257+
};
258+
} // namespace promise_http2_ztrace_collector_detail
259+
260+
using PromiseHttp2ZTraceCollector =
261+
channelz::ZTraceCollector<promise_http2_ztrace_collector_detail::Config,
262+
PromiseEndpointReadTrace,
263+
PromiseEndpointWriteTrace>;
264+
233265
} // namespace grpc_core
234266

235267
#endif // GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_ZTRACE_COLLECTOR_H

test/core/end2end/end2end_ph2_config.cc

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,23 @@
3434

3535
namespace grpc_core {
3636

37+
class Ph2InsecureFixture : public InsecureFixture {
38+
public:
39+
Ph2InsecureFixture() {
40+
// At Least one of the 2 peers MUST be a PH2
41+
GRPC_DCHECK(IsPromiseBasedHttp2ClientTransportEnabled() ||
42+
IsPromiseBasedHttp2ServerTransportEnabled());
43+
}
44+
45+
ChannelArgs MutateClientArgs(ChannelArgs args) override {
46+
return args.Set(GRPC_ARG_ENABLE_CHANNELZ, true);
47+
}
48+
49+
ChannelArgs MutateServerArgs(ChannelArgs args) override {
50+
return args.Set(GRPC_ARG_ENABLE_CHANNELZ, true);
51+
}
52+
};
53+
3754
#define GRPC_HTTP2_PROMISE_CLIENT_TRANSPORT_AVOID_LIST \
3855
"CoreClientChannelTests.DeadlineAfterAcceptWithServiceConfig" \
3956
"|CoreClientChannelTests.DeadlineAfterRoundTripWithServiceConfig" \
@@ -137,7 +154,7 @@ std::vector<CoreTestConfiguration> End2endTestConfigs() {
137154
/*create_fixture=*/
138155
[](const ChannelArgs& /*client_args*/,
139156
const ChannelArgs& /*server_args*/) {
140-
return std::make_unique<InsecureFixture>();
157+
return std::make_unique<Ph2InsecureFixture>();
141158
},
142159
/* include_test_suites */
143160
GRPC_HTTP2_PROMISE_CLIENT_TRANSPORT_ALLOW_SUITE,

0 commit comments

Comments
 (0)