Skip to content

Commit 5fbd644

Browse files
committed
MB-66385: Reduce the number of notifications
Change the behavior of Connection::triggerCallback to only schedule a callback if none will be generated automatically due to data transfer (when all data is moved to kernelspace) Change-Id: Id6b8222cc34ad462977230014bbaa590ac4fa480 Reviewed-on: https://review.couchbase.org/c/kv_engine/+/226752 Tested-by: Build Bot <build@couchbase.com> Reviewed-by: Jim Walker <jim@couchbase.com>
1 parent eeab8bc commit 5fbd644

File tree

7 files changed

+34
-14
lines changed

7 files changed

+34
-14
lines changed

daemon/connection.cc

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -865,10 +865,11 @@ void Connection::tryToProgressDcpStream() {
865865
more = false;
866866
}
867867
}
868-
if (more && (numEvents == 0 || exceededTimeslice)) {
869-
// We used the entire timeslice... schedule a new one
870-
triggerCallback();
871-
}
868+
// There is no need to try to request a "trigger" to continue the
869+
// state machine because we would either have data in the send queue
870+
// causing a callback to arrive (no matter if more is true or false)
871+
// If numevents we would either have data in the output buffer or
872+
// progressing the input stream would already have set up the callback
872873
}
873874

874875
void Connection::processBlockedSendQueue(
@@ -917,7 +918,12 @@ void Connection::processNotifiedCookie(Cookie& cookie, cb::engine_errc status) {
917918
return ptr == cookie.get();
918919
});
919920
}
920-
triggerCallback();
921+
922+
if (!isPacketAvailable()) {
923+
enableReadEvent();
924+
} else {
925+
triggerCallback();
926+
}
921927
} else if (std::chrono::steady_clock::now() > current_timeslice_end) {
922928
++yields;
923929
}
@@ -1336,7 +1342,7 @@ bool Connection::maybeInitiateShutdown(const std::string_view reason) {
13361342
{"reason", reason});
13371343
setTerminationReason(std::move(message));
13381344
shutdown();
1339-
triggerCallback();
1345+
triggerCallback(true);
13401346
return true;
13411347
}
13421348

@@ -1516,7 +1522,7 @@ bool Connection::signalIfIdle() {
15161522
}
15171523

15181524
if (state != State::immediate_close) {
1519-
triggerCallback();
1525+
triggerCallback(true);
15201526
return true;
15211527
}
15221528
return false;

daemon/connection.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -645,8 +645,16 @@ class Connection : public ConnectionIface, public DcpMessageProducersIface {
645645
* Trigger a callback from libevent for the connection at some time
646646
* in the future (as part of the event dispatch loop) so that the
647647
* connection may continue its command execution.
648+
* By default a new callback is only scheduled if there isn't data
649+
* in the send queue as that will generate a callback once the
650+
* data is in the send queue. In some cases we would want the
651+
* callback to be scheduled anyway (for instance when trying to shut
652+
* down a connection which isn't reading its socket). To do so
653+
* set force to true
654+
*
655+
* @param force force a new EV_READ callback to be triggered
648656
*/
649-
virtual void triggerCallback() = 0;
657+
virtual void triggerCallback(bool force = false) = 0;
650658

651659
/// Check if DCP should use the write buffer for the message or if it
652660
/// should use an IOVector to do so

daemon/connection_libevent.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,11 @@ void LibeventConnection::ssl_read_callback(bufferevent* bev, void* ctx) {
340340
LibeventConnection::read_callback(bev, ctx);
341341
}
342342

343-
void LibeventConnection::triggerCallback() {
343+
void LibeventConnection::triggerCallback(bool force) {
344+
if (!force && getSendQueueSize() != 0) {
345+
// The framework will send a notification once the data is sent
346+
return;
347+
}
344348
constexpr auto opt = BEV_TRIG_IGNORE_WATERMARKS | BEV_TRIG_DEFER_CALLBACKS;
345349
bufferevent_trigger(bev.get(), EV_READ, opt);
346350
}

daemon/connection_libevent.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class LibeventConnection : public Connection {
3737
void nextPacket() override;
3838
cb::const_byte_buffer getAvailableBytes() const override;
3939
size_t getSendQueueSize() const override;
40-
void triggerCallback() override;
40+
void triggerCallback(bool force) override;
4141
void disableReadEvent() override;
4242
void enableReadEvent() override;
4343

protocol/mcbp/mcbp_fuzz_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class FuzzConnection : public Connection {
5656
cb::const_byte_buffer getAvailableBytes() const override {
5757
throw std::runtime_error("FuzzConnection: Not implemented");
5858
}
59-
void triggerCallback() override {
59+
void triggerCallback(bool) override {
6060
throw std::runtime_error("FuzzConnection: Not implemented");
6161
}
6262

tests/mcbp/mcbp_mock_connection.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class McbpMockConnection : public Connection {
3737
cb::const_byte_buffer getAvailableBytes() const override {
3838
throw std::runtime_error("MockConnection: Not implemented");
3939
}
40-
void triggerCallback() override {
40+
void triggerCallback(bool) override {
4141
throw std::runtime_error("MockConnection: Not implemented");
4242
}
4343

tests/testapp/testapp_dcp.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,10 @@ TEST_P(DcpTest, DcpStreamStats) {
181181
<< "dcp stats: " << stats.dump(2);
182182
}
183183

184-
/// Verify that we log unclean DCP disconnects
185-
TEST_P(DcpTest, MB60706) {
184+
/// Verify that we log unclean DCP disconnects. Disabled as part of the
185+
/// change to reduce the number of notifications (this changes the scheduling
186+
/// order in the test)
187+
TEST_P(DcpTest, DISABLED_MB60706) {
186188
nlohmann::json json;
187189

188190
std::string value(2048 * 1024, 'a');

0 commit comments

Comments
 (0)