Skip to content

Commit 78a9f40

Browse files
redis: fix pipeline timeout logic (envoyproxy#1773)
Signed-off-by: Daniel Hochman <dhochman@lyft.com>
1 parent c788092 commit 78a9f40

File tree

2 files changed

+14
-8
lines changed

2 files changed

+14
-8
lines changed

source/common/redis/conn_pool_impl.cc

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,18 @@ void ClientImpl::close() { connection_->close(Network::ConnectionCloseType::NoFl
5555

5656
PoolRequest* ClientImpl::makeRequest(const RespValue& request, PoolCallbacks& callbacks) {
5757
ASSERT(connection_->state() == Network::Connection::State::Open);
58+
5859
pending_requests_.emplace_back(*this, callbacks);
5960
encoder_->encode(request, encoder_buffer_);
6061
connection_->write(encoder_buffer_);
6162

62-
// Only boost the op timeout if we are not already connected. Otherwise, we are governed by
63-
// the connect timeout and the timer will be reset when/if connection occurs. This allows a
64-
// relatively long connection spin up time for example if TLS is being used.
65-
if (connected_) {
63+
// Only boost the op timeout if:
64+
// - We are not already connected. Otherwise, we are governed by the connect timeout and the timer
65+
// will be reset when/if connection occurs. This allows a relatively long connection spin up
66+
// time for example if TLS is being used.
67+
// - This is the first request on the pipeline. Otherwise the timeout would effectively start on
68+
// the last operation.
69+
if (connected_ && pending_requests_.size() == 1) {
6670
connect_or_op_timer_->enableTimer(config_.opTimeout());
6771
}
6872

@@ -137,10 +141,12 @@ void ClientImpl::onRespValue(RespValuePtr&& value) {
137141
}
138142
pending_requests_.pop_front();
139143

140-
// We boost the op timeout every time we pipeline a new op. However, if there are no remaining
141-
// ops in the pipeline we need to disable the timer.
144+
// If there are no remaining ops in the pipeline we need to disable the timer.
145+
// Otherwise we boost the timer since we are receiving responses and there are more to flush out.
142146
if (pending_requests_.empty()) {
143147
connect_or_op_timer_->disableTimer();
148+
} else {
149+
connect_or_op_timer_->enableTimer(config_.opTimeout());
144150
}
145151

146152
host_->outlierDetector().putHttpResponseCode(enumToInt(Http::Code::OK));

test/common/redis/conn_pool_impl_test.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ TEST_F(RedisClientImplTest, Basic) {
106106
RespValue request2;
107107
MockPoolCallbacks callbacks2;
108108
EXPECT_CALL(*encoder_, encode(Ref(request2), _));
109-
EXPECT_CALL(*connect_or_op_timer_, enableTimer(_));
110109
PoolRequest* handle2 = client_->makeRequest(request2, callbacks2);
111110
EXPECT_NE(nullptr, handle2);
112111

@@ -120,6 +119,7 @@ TEST_F(RedisClientImplTest, Basic) {
120119
InSequence s;
121120
RespValuePtr response1(new RespValue());
122121
EXPECT_CALL(callbacks1, onResponse_(Ref(response1)));
122+
EXPECT_CALL(*connect_or_op_timer_, enableTimer(_));
123123
EXPECT_CALL(host_->outlier_detector_, putHttpResponseCode(200));
124124
callbacks_->onRespValue(std::move(response1));
125125

@@ -152,7 +152,6 @@ TEST_F(RedisClientImplTest, Cancel) {
152152
RespValue request2;
153153
MockPoolCallbacks callbacks2;
154154
EXPECT_CALL(*encoder_, encode(Ref(request2), _));
155-
EXPECT_CALL(*connect_or_op_timer_, enableTimer(_));
156155
PoolRequest* handle2 = client_->makeRequest(request2, callbacks2);
157156
EXPECT_NE(nullptr, handle2);
158157

@@ -164,6 +163,7 @@ TEST_F(RedisClientImplTest, Cancel) {
164163

165164
RespValuePtr response1(new RespValue());
166165
EXPECT_CALL(callbacks1, onResponse_(_)).Times(0);
166+
EXPECT_CALL(*connect_or_op_timer_, enableTimer(_));
167167
EXPECT_CALL(host_->outlier_detector_, putHttpResponseCode(200));
168168
callbacks_->onRespValue(std::move(response1));
169169

0 commit comments

Comments
 (0)