Skip to content

Commit bfe88e0

Browse files
ac-patelcopybara-github
authored andcommitted
[PH2][Keepalive] Move spawn into the transport
PiperOrigin-RevId: 856971493
1 parent 9e803ba commit bfe88e0

5 files changed

Lines changed: 60 additions & 39 deletions

File tree

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1504,7 +1504,7 @@ Http2ClientTransport::Http2ClientTransport(
15041504
KeepAliveInterfaceImpl::Make(this),
15051505
((args.keepalive_timeout < args.ping_timeout) ? args.keepalive_timeout
15061506
: Duration::Infinity()),
1507-
args.keepalive_time, general_party_.get());
1507+
args.keepalive_time);
15081508

15091509
GRPC_DCHECK(ping_manager_.has_value());
15101510
GRPC_DCHECK(keepalive_manager_.has_value());
@@ -1514,6 +1514,7 @@ Http2ClientTransport::Http2ClientTransport(
15141514

15151515
void Http2ClientTransport::SpawnTransportLoops() {
15161516
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::SpawnTransportLoops Begin";
1517+
MaybeSpawnKeepaliveLoop();
15171518
SpawnGuardedTransportParty(
15181519
"FlowControlPeriodicUpdateLoop",
15191520
UntilTransportClosed(FlowControlPeriodicUpdateLoop()));
@@ -2252,6 +2253,15 @@ void Http2ClientTransport::MaybeSpawnDelayedPing(
22522253
}
22532254
}
22542255

2256+
void Http2ClientTransport::MaybeSpawnKeepaliveLoop() {
2257+
if (keepalive_manager_->IsKeepAliveLoopNeeded()) {
2258+
SpawnGuardedTransportParty(
2259+
"KeepaliveLoop", [self = RefAsSubclass<Http2ClientTransport>()]() {
2260+
return self->keepalive_manager_->KeepaliveLoop();
2261+
});
2262+
}
2263+
}
2264+
22552265
///////////////////////////////////////////////////////////////////////////////
22562266
// Class PingSystemInterfaceImpl
22572267

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ class Http2ClientTransport final : public ClientTransport,
389389
std::optional<KeepaliveManager> keepalive_manager_;
390390
void MaybeSpawnPingTimeout(std::optional<uint64_t> opaque_data);
391391
void MaybeSpawnDelayedPing(std::optional<Duration> delayed_ping_wait);
392+
void MaybeSpawnKeepaliveLoop();
392393

393394
// Flags
394395
bool keepalive_permit_without_calls_;

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

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "src/core/lib/promise/if.h"
2424
#include "src/core/lib/promise/loop.h"
2525
#include "src/core/lib/promise/party.h"
26+
#include "src/core/lib/promise/promise.h"
2627
#include "src/core/lib/promise/race.h"
2728
#include "src/core/lib/promise/sleep.h"
2829
#include "src/core/lib/promise/try_seq.h"
@@ -33,12 +34,10 @@ namespace grpc_core {
3334
namespace http2 {
3435
KeepaliveManager::KeepaliveManager(
3536
std::unique_ptr<KeepAliveInterface> keep_alive_interface,
36-
Duration keepalive_timeout, const Duration keepalive_time, Party* party)
37+
Duration keepalive_timeout, const Duration keepalive_time)
3738
: keep_alive_interface_(std::move(keep_alive_interface)),
3839
keepalive_timeout_(keepalive_timeout),
39-
keepalive_time_(keepalive_time) {
40-
MaybeSpawnKeepaliveLoop(party);
41-
}
40+
keepalive_time_(keepalive_time) {}
4241

4342
auto KeepaliveManager::WaitForKeepAliveTimeout() {
4443
return AssertResultType<absl::Status>(
@@ -90,23 +89,18 @@ auto KeepaliveManager::MaybeSendKeepAlivePing() {
9089
}));
9190
}
9291

93-
void KeepaliveManager::MaybeSpawnKeepaliveLoop(Party* party) {
94-
if (!IsKeepAliveNeeded()) {
95-
GRPC_HTTP2_KEEPALIVE_LOG << "Not spawning keepalive loop.";
96-
return;
97-
}
98-
keep_alive_spawned_ = true;
92+
bool KeepaliveManager::IsKeepAliveLoopNeeded() {
93+
return IsKeepAliveNeeded() && !keep_alive_spawned_;
94+
}
9995

100-
party->Spawn("KeepAliveLoop", Loop([this]() {
101-
return TrySeq(
102-
Sleep(keepalive_time_),
103-
[this]() { return MaybeSendKeepAlivePing(); },
104-
[]() -> LoopCtl<absl::Status> { return Continue(); });
105-
}),
106-
[](auto status) {
107-
GRPC_HTTP2_KEEPALIVE_LOG << "KeepAlive end with status: "
108-
<< status;
109-
});
96+
Promise<absl::Status> KeepaliveManager::KeepaliveLoop() {
97+
GRPC_HTTP2_KEEPALIVE_LOG << "KeepaliveManager::KeepaliveLoop Spawning.";
98+
keep_alive_spawned_ = true;
99+
return Loop([this]() {
100+
return TrySeq(
101+
Sleep(keepalive_time_), [this]() { return MaybeSendKeepAlivePing(); },
102+
[]() -> LoopCtl<absl::Status> { return Continue(); });
103+
});
110104
}
111105
} // namespace http2
112106
} // namespace grpc_core

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
#ifndef GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_KEEPALIVE_H
1919
#define GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_KEEPALIVE_H
2020

21+
#include "src/core/lib/promise/loop.h"
2122
#include "src/core/lib/promise/party.h"
2223
#include "src/core/lib/promise/promise.h"
24+
#include "src/core/lib/promise/sleep.h"
2325
#include "src/core/util/grpc_check.h"
2426
#include "absl/status/status.h"
2527

@@ -45,8 +47,7 @@ class KeepAliveInterface {
4547
class KeepaliveManager {
4648
public:
4749
KeepaliveManager(std::unique_ptr<KeepAliveInterface> keep_alive_interface,
48-
Duration keepalive_timeout, Duration keepalive_time,
49-
Party* party);
50+
Duration keepalive_timeout, Duration keepalive_time);
5051

5152
// Needs to be called when any data is read from the endpoint.
5253
void GotData() {
@@ -66,11 +67,13 @@ class KeepaliveManager {
6667
keepalive_timeout_ = keepalive_timeout;
6768
}
6869

69-
private:
70-
// Spawns the keepalive loop on the given party. This MUST be called at most
71-
// once during the lifetime of the keepalive manager.
72-
void MaybeSpawnKeepaliveLoop(Party* party);
70+
bool IsKeepAliveLoopNeeded();
71+
72+
// Returns a promise that processes keepalive pings. This MUST be called at
73+
// most once during the lifetime of the keepalive manager.
74+
Promise<absl::Status> KeepaliveLoop();
7375

76+
private:
7477
// Returns a promise that sleeps for the keepalive_timeout_ and triggers the
7578
// keepalive timeout unless data is read within the keepalive timeout.
7679
auto WaitForKeepAliveTimeout();

test/core/transport/chttp2/keepalive_test.cc

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,17 @@ class MockKeepAliveInterface : public KeepAliveInterface {
8888
}
8989
};
9090

91+
void MaybeSpawnKeepaliveLoop(KeepaliveManager& keepalive_manager,
92+
Party* party) {
93+
if (keepalive_manager.IsKeepAliveLoopNeeded()) {
94+
party->Spawn(
95+
"KeepaliveLoop", [&]() { return keepalive_manager.KeepaliveLoop(); },
96+
[](absl::Status status) {
97+
LOG(INFO) << "KeepaliveLoop end with status: " << status;
98+
});
99+
}
100+
}
101+
91102
class KeepaliveManagerTest : public YodelTest {
92103
protected:
93104
using YodelTest::YodelTest;
@@ -122,17 +133,17 @@ YODEL_TEST(KeepaliveManagerTest, TestKeepAlive) {
122133
/*return_value=*/true);
123134

124135
KeepaliveManager keep_alive_system(std::move(keep_alive_interface),
125-
keepalive_timeout, keepalive_interval,
126-
GetParty());
136+
keepalive_timeout, keepalive_interval);
137+
MaybeSpawnKeepaliveLoop(keep_alive_system, GetParty());
127138

128139
WaitForAllPendingWork();
129140
event_engine()->TickUntilIdle();
130141
event_engine()->UnsetGlobalHooks();
131142
}
132143

133144
YODEL_TEST(KeepaliveManagerTest, TestKeepAliveTimeout) {
134-
// Simple test to simulate sending a keepalive ping and not receiving any data
135-
// within the keepalive timeout. The test asserts that:
145+
// Simple test to simulate sending a keepalive ping and not receiving any
146+
// data within the keepalive timeout. The test asserts that:
136147
// 1. The keepalive timeout is triggered.
137148
// 2. The keepalive ping is sent.
138149
InitParty();
@@ -148,8 +159,8 @@ YODEL_TEST(KeepaliveManagerTest, TestKeepAliveTimeout) {
148159
/*return_value=*/true);
149160

150161
KeepaliveManager keep_alive_system(std::move(keep_alive_interface),
151-
keepalive_timeout, keepalive_interval,
152-
GetParty());
162+
keepalive_timeout, keepalive_interval);
163+
MaybeSpawnKeepaliveLoop(keep_alive_system, GetParty());
153164

154165
WaitForAllPendingWork();
155166
event_engine()->TickUntilIdle();
@@ -159,7 +170,8 @@ YODEL_TEST(KeepaliveManagerTest, TestKeepAliveTimeout) {
159170
YODEL_TEST(KeepaliveManagerTest, TestKeepAliveWithData) {
160171
// Test to simulate reading of data at certain intervals. The test asserts
161172
// that:
162-
// 1. The keepalive ping is not sent as long as there is data read within the
173+
// 1. The keepalive ping is not sent as long as there is data read within
174+
// the
163175
// keepalive interval.
164176
InitParty();
165177
int end_after = 1;
@@ -175,8 +187,8 @@ YODEL_TEST(KeepaliveManagerTest, TestKeepAliveWithData) {
175187
/*return_value=*/true);
176188

177189
KeepaliveManager keep_alive_system(std::move(keep_alive_interface),
178-
keepalive_timeout, keepalive_interval,
179-
GetParty());
190+
keepalive_timeout, keepalive_interval);
191+
MaybeSpawnKeepaliveLoop(keep_alive_system, GetParty());
180192

181193
GetParty()->Spawn(
182194
"ReadData", Loop([&read_loop_end_after, &keep_alive_system]() {
@@ -200,7 +212,8 @@ YODEL_TEST(KeepaliveManagerTest, TestKeepAliveWithData) {
200212
YODEL_TEST(KeepaliveManagerTest, TestKeepAliveTimeoutWithData) {
201213
// Test to simulate reading of data at certain intervals. The test asserts
202214
// that:
203-
// 1. The keepalive ping is not sent as long as there is data read within the
215+
// 1. The keepalive ping is not sent as long as there is data read within
216+
// the
204217
// keepalive interval.
205218
// 2. Keepalive timeout is triggered once no data is read within the
206219
// keepalive timeout.
@@ -219,8 +232,8 @@ YODEL_TEST(KeepaliveManagerTest, TestKeepAliveTimeoutWithData) {
219232
/*return_value=*/true);
220233

221234
KeepaliveManager keep_alive_system(std::move(keep_alive_interface),
222-
keepalive_timeout, keepalive_interval,
223-
GetParty());
235+
keepalive_timeout, keepalive_interval);
236+
MaybeSpawnKeepaliveLoop(keep_alive_system, GetParty());
224237

225238
GetParty()->Spawn(
226239
"ReadData", Loop([&read_loop_end_after, &keep_alive_system]() {

0 commit comments

Comments
 (0)