Skip to content

Commit e2806ea

Browse files
DemetrisChravsej
authored andcommitted
CCBC-1647: Handle server-side query timeout (status 1080)
Motivation ========== The 1080 (timeout) query status is not being handled. This means that if the server times out before the client, we return LCB_SUCCESS with an incomplete set of rows instead of LCB_ERR_TIMEOUT. Typically the client will time out before the server, however, it's possible for the server to time out first if the query grace period is set to something high enough. Changes ======= Return LCB_ERR_TIMEOUT when query returns the 1080 status code in the response body Results ======= Test passes Change-Id: I309198fb864c0eb8e3050ac64391b30833c85a5e Reviewed-on: https://review.couchbase.org/c/libcouchbase/+/215620 Reviewed-by: Sergey Avseyev <[email protected]> Tested-by: Build Bot <[email protected]>
1 parent 872c6c6 commit e2806ea

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

src/n1ql/query_handle.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ bool lcb_QUERY_HANDLE_::parse_meta(const char *row, size_t row_len, lcb_STATUS &
122122
if (code.isNumeric()) {
123123
first_error.code = code.asUInt();
124124
switch (first_error.code) {
125+
case 1080:
126+
rc = LCB_ERR_TIMEOUT;
127+
break;
125128
case 3000:
126129
rc = LCB_ERR_PARSING_FAILURE;
127130
break;

tests/iotests/t_n1ql.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,3 +1162,32 @@ TEST_F(QueryUnitTest, testReadOnlyWithNoResults)
11621162
ASSERT_STATUS_EQ(LCB_SUCCESS, res.rc);
11631163
ASSERT_EQ(0, res.rows.size());
11641164
}
1165+
1166+
TEST_F(QueryUnitTest, testQueryServerTimeout)
1167+
{
1168+
SKIP_IF_MOCK()
1169+
HandleWrap hw;
1170+
lcb_INSTANCE *instance;
1171+
createConnection(hw, &instance);
1172+
1173+
// Setting a very large grace period so the server-side timeout is returned before the client times out
1174+
lcb_cntl_setu32(instance, LCB_CNTL_QUERY_GRACE_PERIOD, 100000000);
1175+
1176+
N1QLResult res;
1177+
lcb_CMDQUERY *cmd;
1178+
lcb_cmdquery_create(&cmd);
1179+
string query = "WITH x AS (ARRAY_RANGE(0,100000)) SELECT * FROM x";
1180+
lcb_cmdquery_statement(cmd, query.c_str(), query.size());
1181+
lcb_cmdquery_timeout(cmd, 10000);
1182+
lcb_cmdquery_callback(cmd, rowcb);
1183+
1184+
lcb_QUERY_HANDLE *handle = nullptr;
1185+
lcb_cmdquery_handle(cmd, &handle);
1186+
lcb_STATUS rc = lcb_query(instance, &res, cmd);
1187+
lcb_cmdquery_destroy(cmd);
1188+
ASSERT_STATUS_EQ(LCB_SUCCESS, rc);
1189+
ASSERT_TRUE(handle != nullptr);
1190+
lcb_wait(instance, LCB_WAIT_DEFAULT);
1191+
ASSERT_TRUE(res.called);
1192+
ASSERT_STATUS_EQ(LCB_ERR_TIMEOUT, res.rc) << "http=" << res.htcode << ", meta=" << res.meta;
1193+
}

0 commit comments

Comments
 (0)