Skip to content

Commit

Permalink
Bind timeout function for Node.js APIs (#2311)
Browse files Browse the repository at this point in the history
* Bind timeout functions for Node.js APIs

* Format

* Bump version number to 0.0.12
  • Loading branch information
mewim committed Oct 31, 2023
1 parent 2021979 commit 43128fc
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 28 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.11)

project(Kuzu VERSION 0.0.11 LANGUAGES CXX C)
project(Kuzu VERSION 0.0.12 LANGUAGES CXX C)

find_package(Threads REQUIRED)

Expand Down
2 changes: 1 addition & 1 deletion src/include/common/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace kuzu {
namespace common {

constexpr char KUZU_VERSION[] = "v0.0.11";
constexpr char KUZU_VERSION[] = "v0.0.12";

constexpr uint64_t DEFAULT_VECTOR_CAPACITY_LOG_2 = 11;
constexpr uint64_t DEFAULT_VECTOR_CAPACITY = (uint64_t)1 << DEFAULT_VECTOR_CAPACITY_LOG_2;
Expand Down
4 changes: 2 additions & 2 deletions src/include/storage/storage_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ using storage_version_t = uint64_t;

struct StorageVersionInfo {
static std::unordered_map<std::string, storage_version_t> getStorageVersionInfo() {
return {{"0.0.11", 23}, {"0.0.10", 23}, {"0.0.9", 23}, {"0.0.8", 17}, {"0.0.7", 15},
{"0.0.6", 9}, {"0.0.5", 8}, {"0.0.4", 7}, {"0.0.3", 1}};
return {{"0.0.12", 23}, {"0.0.11", 23}, {"0.0.10", 23}, {"0.0.9", 23}, {"0.0.8", 17},
{"0.0.7", 15}, {"0.0.6", 9}, {"0.0.5", 8}, {"0.0.4", 7}, {"0.0.3", 1}};
}

static storage_version_t getStorageVersion();
Expand Down
2 changes: 1 addition & 1 deletion test/test_files/tinysnb/function/table.test
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ height
-LOG ReturnDBVersion
-STATEMENT CALL db_version() RETURN version
---- 1
v0.0.11
v0.0.12

-LOG ReturnTableConnection
-STATEMENT CALL show_connection('knows') RETURN *
Expand Down
1 change: 1 addition & 0 deletions tools/nodejs_api/src_cpp/include/node_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class NodeConnection : public Napi::ObjectWrap<NodeConnection> {
Napi::Value InitAsync(const Napi::CallbackInfo& info);
void InitCppConnection();
void SetMaxNumThreadForExec(const Napi::CallbackInfo& info);
void SetQueryTimeout(const Napi::CallbackInfo& info);
Napi::Value ExecuteAsync(const Napi::CallbackInfo& info);

private:
Expand Down
35 changes: 23 additions & 12 deletions tools/nodejs_api/src_cpp/node_connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Napi::Object NodeConnection::Init(Napi::Env env, Napi::Object exports) {
InstanceMethod("initAsync", &NodeConnection::InitAsync),
InstanceMethod("executeAsync", &NodeConnection::ExecuteAsync),
InstanceMethod("setMaxNumThreadForExec", &NodeConnection::SetMaxNumThreadForExec),
InstanceMethod("setQueryTimeout", &NodeConnection::SetQueryTimeout),
});

exports.Set("NodeConnection", t);
Expand Down Expand Up @@ -44,6 +45,28 @@ void NodeConnection::InitCppConnection() {
database.reset();
}

void NodeConnection::SetMaxNumThreadForExec(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
size_t numThreads = info[0].ToNumber().Int64Value();
try {
this->connection->setMaxNumThreadForExec(numThreads);
} catch (const std::exception& exc) {
Napi::Error::New(env, std::string(exc.what())).ThrowAsJavaScriptException();
}
}

void NodeConnection::SetQueryTimeout(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
size_t timeout = info[0].ToNumber().Int64Value();
try {
this->connection->setQueryTimeOut(timeout);
} catch (const std::exception& exc) {
Napi::Error::New(env, std::string(exc.what())).ThrowAsJavaScriptException();
}
}

Napi::Value NodeConnection::ExecuteAsync(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
Expand All @@ -62,15 +85,3 @@ Napi::Value NodeConnection::ExecuteAsync(const Napi::CallbackInfo& info) {
}
return info.Env().Undefined();
}

void NodeConnection::SetMaxNumThreadForExec(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
size_t numThreads = info[0].ToNumber().Int64Value();
try {
this->connection->setMaxNumThreadForExec(numThreads);
} catch (const std::exception& exc) {
Napi::Error::New(env, std::string(exc.what())).ThrowAsJavaScriptException();
}
}

28 changes: 26 additions & 2 deletions tools/nodejs_api/src_js/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ class Connection {
if (this._numThreads) {
this._connection.setMaxNumThreadForExec(this._numThreads);
}
if (this._queryTimeout) {
this._connection.setQueryTimeout(this._queryTimeout);
}
resolve();
}
});
Expand Down Expand Up @@ -194,10 +197,31 @@ class Connection {
if (typeof numThreads !== "number" || !numThreads || numThreads < 0) {
throw new Error("numThreads must be a positive number.");
}
if (!this.isInitialized) {
if (this._isInitialized) {
this._connection.setMaxNumThreadForExec(numThreads);
} else {
this._numThreads = numThreads;
}
}

/**
* Set the timeout for queries. Queries that take longer than the timeout
* will be aborted.
* @param {Number} timeoutInMs the timeout in milliseconds.
*/
setQueryTimeout(timeoutInMs) {
if (
typeof timeoutInMs !== "number" ||
isNaN(timeoutInMs) ||
timeoutInMs <= 0
) {
throw new Error("timeoutInMs must be a positive number.");
}
if (this._isInitialized) {
this._connection.setQueryTimeout(timeoutInMs);
} else {
this._queryTimeout = timeoutInMs;
}
this._numThreads = numThreads;
}
}

Expand Down
40 changes: 32 additions & 8 deletions tools/nodejs_api/test/test_connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,7 @@ describe("Execute", function () {
await conn.execute(preparedStatement, { 1: 0 });
assert.fail("No error thrown when the prepared statement is invalid.");
} catch (e) {
assert.equal(
e.message,
"Binder exception: Table dog does not exist."
);
assert.equal(e.message, "Binder exception: Table dog does not exist.");
}
});

Expand Down Expand Up @@ -185,10 +182,7 @@ describe("Query", function () {
await conn.query("MATCH (a:dog) RETURN COUNT(*)");
assert.fail("No error thrown when the query is invalid.");
} catch (e) {
assert.equal(
e.message,
"Binder exception: Table dog does not exist."
);
assert.equal(e.message, "Binder exception: Table dog does not exist.");
}
});

Expand All @@ -201,3 +195,33 @@ describe("Query", function () {
}
});
});

describe("Timeout", function () {
it("should abort a query if the timeout is reached", async function () {
try {
const newConn = new kuzu.Connection(db);
await newConn.init();
newConn.setQueryTimeout(1);
await newConn.query(
"MATCH (a:person)-[:knows*1..28]->(b:person) RETURN COUNT(*);"
);
assert.fail("No error thrown when the query times out.");
} catch (err) {
assert.equal(err.message, "Interrupted.");
}
});

it("should allow setting a timeout before the connection is initialized", async function () {
try {
const newConn = new kuzu.Connection(db);
newConn.setQueryTimeout(1);
await newConn.init();
await newConn.query(
"MATCH (a:person)-[:knows*1..28]->(b:person) RETURN COUNT(*);"
);
assert.fail("No error thrown when the query times out.");
} catch (err) {
assert.equal(err.message, "Interrupted.");
}
});
});
2 changes: 1 addition & 1 deletion tools/rust_api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "kuzu"
version = "0.0.11"
version = "0.0.12"
description = "An in-process property graph database management system built for query speed and scalability"
# Note: 1.63 required for building tests
rust-version = "1.51"
Expand Down

0 comments on commit 43128fc

Please sign in to comment.