Skip to content

Commit 884038e

Browse files
committed
CCBC-1616: apply wait_for_config check for all pipelines
When the connection is slow, or operation timeout is configured to pretty low value, the SDK might not leave the event loop in case, when lcb_wait() function is being used to execute IO operations. In this case, regardless that actual data operation has been completed, and user callback invoked, the library might have configuration update operation running, and will wait for its completion, even though it is not required to return control from lcb_wait() operation by default. Change-Id: Ia58cb6632f3b4d17ac01b75e71b6baaddbbde2f6 Reviewed-on: https://review.couchbase.org/c/libcouchbase/+/198057 Tested-by: Build Bot <[email protected]> Reviewed-by: Sergey Avseyev <[email protected]>
1 parent 67f73a1 commit 884038e

File tree

5 files changed

+32
-5
lines changed

5 files changed

+32
-5
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
.deps/
2727
.libs/
2828
/INSTALL
29+
/.cache
2930
/Makefile
3031
/Makefile.in
3132
/aclocal.m4

src/mcserver/mcserver.cc

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,3 +1382,30 @@ bool Server::check_closed()
13821382
finalize_errored_ctx();
13831383
return true;
13841384
}
1385+
1386+
bool Server::has_pending(bool ignore_cfgreq) const
1387+
{
1388+
if (ignore_cfgreq) {
1389+
sllist_node *ll;
1390+
SLLIST_FOREACH(&requests, ll)
1391+
{
1392+
const mc_PACKET *pkt = SLLIST_ITEM(ll, mc_PACKET, slnode);
1393+
protocol_binary_request_header hdr = {};
1394+
mcreq_read_hdr(pkt, &hdr);
1395+
/*
1396+
* return true immediately if there is a pending request, that is not related to
1397+
* configuration updates
1398+
*/
1399+
if (hdr.request.opcode != PROTOCOL_BINARY_CMD_GET_CLUSTER_CONFIG &&
1400+
hdr.request.opcode != PROTOCOL_BINARY_CMD_SELECT_BUCKET) {
1401+
return true;
1402+
}
1403+
}
1404+
/*
1405+
* the pending requests list is empty or contains only configuration update requests
1406+
* in any case consider it empty, because of ignore_cfgreq flag
1407+
*/
1408+
return false;
1409+
}
1410+
return !SLLIST_IS_EMPTY(&requests);
1411+
}

src/mcserver/mcserver.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,7 @@ class Server : public mc_PIPELINE
8181
* Returns true or false depending on whether there are pending commands on
8282
* this server
8383
*/
84-
bool has_pending() const
85-
{
86-
return !SLLIST_IS_EMPTY(&requests);
87-
}
84+
bool has_pending(bool ignore_cfgreq = false) const;
8885

8986
int get_index() const
9087
{

src/wait.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ static bool has_pending(lcb_INSTANCE *instance)
3232
}
3333

3434
for (size_t ii = 0; ii < LCBT_NSERVERS(instance); ii++) {
35-
if (instance->get_server(ii)->has_pending()) {
35+
if (instance->get_server(ii)->has_pending(!LCBT_SETTING(instance, wait_for_config))) {
3636
return true;
3737
}
3838
}

tests/iotests/t_get.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,8 @@ TEST_F(GetUnitTest, testFailoverAndGetReplica)
583583
lcb_cntl(instance, LCB_CNTL_SET, LCB_CNTL_OP_TIMEOUT, &tmoval);
584584
// Reduce configuration poll interval to get new configuration sooner
585585
lcb_cntl(instance, LCB_CNTL_SET, LCB_CNTL_CONFIG_POLL_INTERVAL, &tmoval);
586+
std::uint32_t yes = 1;
587+
lcb_cntl(instance, LCB_CNTL_SET, LCB_CNTL_WAIT_FOR_CONFIG, &yes);
586588

587589
// store keys
588590
size_t counter = 0;

0 commit comments

Comments
 (0)