Skip to content
Open

v4 #56

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 0 additions & 38 deletions .eslintrc

This file was deleted.

52 changes: 52 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Tests

on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]

jobs:
test:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [20, 22, 24]

steps:
- uses: actions/checkout@v4

- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}

- name: Install dependencies
run: npm install

- name: Start Tarantool container
run: |
docker run \
--name tarantool-test-box \
-v ${{ github.workspace }}/assets:/opt/tarantool \
-v /tmp:/tmp \
--rm \
-d \
-p 3301:3301 \
-e TT_DATABASE_USE_MVCC_ENGINE=true \
-e TT_IPROTO_THREADS=2 \
tarantool/tarantool:latest tarantool /opt/tarantool/box.lua

- name: Wait for Tarantool to be ready
run: sleep 2

- name: Lint
run: npm run lint

- name: Run tests
run: npm test

- name: Stop Tarantool container
if: always()
run: docker stop tarantool-test-box || true
9 changes: 0 additions & 9 deletions .gitignore

This file was deleted.

23 changes: 0 additions & 23 deletions .travis.yml

This file was deleted.

19 changes: 19 additions & 0 deletions BENCHMARK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# How to

1. Start the Tarantool server on your machine with a [box.lua](assets/box.lua) config located in a `test` folder.
2. Execute the following:
```Bash
npm run benchmark-write
```
to fill all of the spaces with data and check the insert performance.
3. Execute the following:
```Bash
npm run benchmark-write
```
to test the read performance of previously added tuples

# "Read" results
- Machine: Apple Macbook Air M2 2022 8GB RAM
- `node -v`: 24.3.0

![results table of "read" benchmark](assets/read-results-table.png)
130 changes: 130 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
## 4.0.0

### <b>BREAKING</b>
- `nonWritableHostPolicy` is deprecated and no more supported due to the overhead, low-frequency usability and complexity. Finally, it may be better to handle the connection's 'close' errors by developer and reconnect.
- For a syntax clearance and new features you should pass parameters of `eval` and `call` methods as an array, e.g.:
```javascript
tarantool.eval('return ...', [a, b])
```
instead of the previous:
```javascript
tarantool.eval('return ...', a, b)
```
- Dropping support for old Node.JS versions:
now this module is guaranteed to work on a `Maintenance`, `Active` and `Current` [versions](https://nodejs.org/en/about/previous-releases#release-schedule) in order to introduce new features and stability.
- `selectCb()` method is deprecated. This (`.select()`) and all other commands now can be invoked in a callback style (but `then/catch`-style is also supported, just don't specify the `cb` parameter and the function will return a Promise):
```javascript
tarantool.select(
spaceId,
indexId,
limit,
offset,
iterator,
key,
opts,
(error, success) => {
// process the result as usual
}
)
```

### Bug fixes
- Fixed bug of a buffer reuse approach
- Fixed use of keepAlive and noDelay
- Fixed use of Transactions if connection is not inited yet
- Fixed memory leak of 'connect' / 'close' events (appeared during many reconnects)

### Improvements
- Optimized offline queue
- New option `tupleToObject`, which allows you to receive an array of objects instead of array of arrays:
- Keys are similar to the Tarantool space's key names, and value is a corresponding value from the tuple
- Note that there is an extra overhead of converting array to object
- This option is usable only for the following request types: `select`, `update`, `delete`, `insert`, `replace`
- Introduced 2 custom error classes, which are exported on the connector class. They are useful for a better development experience when you can handle errors more properly:
- ReplyError: errors created by the Tarantool server in a similar [format](https://www.tarantool.io/ru/doc/latest/reference/internals/msgpack_extensions/#the-error-type)
- TarantoolError: general errors thrown by the driver
- New option `commandTimeout` to define the max execution time of the sent request. Can be configured on the class globally or per each command
- `packDecimal()` function now also accepts BigInt
- Improved performance of the built-in MsgPack extensions (used in a `packDecimal()`, `packUuid()`, etc)
- Improved compression of the 'update' / 'upsert' operations by converting a string field names to their corresponding ID's
- New iterators: OVERLAPS and NEIGHBOR
- Extended tests (with help of a native `node:test` and `node:assert`)
- Updated benchmarks, README, eslint config
- New guides
- Even better performance
- New `.quit()` method - awaits for the sent commands to become fullfilled before the connection closes
- Pipeline response is now an instance of `PipelineResponse` with 2 additional methods: `findPipelineError()` and `findPipelineErrors()`

## 3.2.0

- Now supports [prepared](https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_sql/prepare/#box-sql-box-prepare) SQL statements.
- Huge rewrite of the codebase, which improved the performance:
- Now using 'msgpackr' instead of 'msgpack-lite'
- Buffer reuse
- Decreased memory consumption
- New AutoPipelining mode: optimise performance with no need to rewrite your existing code. Benchmark showed x4 performance for the `select` requests:
- 350k/sec without AutoPipelining
- 1400k/sec with AutoPipelining feature enabled
- [IPROTO_ID](https://www.tarantool.io/en/doc/latest/reference/internals/iproto/requests/#iproto-id) can be invoked as 'conn.id()' function.
- [Streams](https://www.tarantool.io/en/doc/latest/platform/atomic/txn_mode_mvcc/#streams-and-interactive-transactions) support.

## 3.1.0

- Added 3 new msgpack extensions: UUID, Datetime, Decimal.
- Connection object now accepts all options of `net.createConnection()`, including Unix socket path.
- New `nonWritableHostPolicy` and related options, which improves a high availability capabilities without any 3rd parties.
- Ability to disable the offline queue.
- Fixed [bug with int32](https://github.com/tarantool/node-tarantool-driver/issues/48) numbers when it was encoded as floating. Use method `packInteger()` to solve this.
- `selectCb()` now also accepts `spaceId` and `indexId` as their String names, not only their IDs.
- Some performance improvements by caching internal values.
- TLS (SSL) support.
- New `pipeline()`+`exec()` methods kindly borrowed from the [ioredis](https://github.com/redis/ioredis?tab=readme-ov-file#pipelining), which lets you to queue some commands in memory and then send them simultaneously to the server in a single (or several, if request body is too big) network call(s). Thanks to the Tarantool, which [made this possible](https://www.tarantool.io/en/doc/latest/dev_guide/internals/iproto/format/#packet-structure).
This way the performance is significantly improved by 500-1600% - you can check it yourself by running `npm run benchmark-read` or `npm run benchmark-write`.
Note that this feature doesn't replaces the Transaction model, which has some level of isolation.
- Changed `const` declaration to `var` in order to support old Node.JS versions.

## 3.0.7

Fix in header decoding to support latest Tarantool versions. Update to tests to support latest Tarantool versions.

## 3.0.6

Remove let for support old nodejs version

## 3.0.5

Add support SQL

## 3.0.4

Fix eval and call

## 3.0.3

Increase request id limit to SMI Maximum

## 3.0.2

Fix parser thx @tommiv

## 3.0.0

New version with reconnect in alpha.

## 1.0.0

Fix test for call changes and remove unuse upsert parameter (critical change API for upsert)

## 0.4.1

Add clear schema cache on change schema id

## 0.4.0

Change msgpack5 to msgpack-lite(thx to @arusakov).
Add msgpack as option for connection.
Bump msgpack5 for work at new version.

## 0.3.0
Add upsert operation.
Key is now can be just a number.
15 changes: 15 additions & 0 deletions PERFORMANCE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Performance optimization guide

- Consider connecting to Tarantool server via an UNIX-socket path. Benchmark shows that it could double the performance (more throughput, less latency) than connection to a basic `host:port`.
- Increase `sliderBufferInitialSize` option if you are facing a high-frequency or big (for example: large `.insert()` tuple, long multi-part indexes for `.select()`, etc) requests.
- Set `enableAutoPipelining` option to `true`. This approach may significantly improve the performance by 2-4 times with a small trade-off in the form of a bit increased query execution time (just a several milliseconds usually).
- This works by collecting request's buffers and not sending them immediately to server. Instead of this, connector stores the pending buffers, waits till the next tick, concatenates all the data and sends it in a big single batch.
- You may also use `.pipeline()` and `.exec()` to manually control which data should be sent in a single batch and which not. In this case the requests latency will not be increased <i>(because there will be no dispatching to the next tick)</i> and your code will benefit from less calls to `socket.write()`
- This approach was gently borrowed from [ioredis - read more](https://github.com/redis/ioredis?tab=readme-ov-file#autopipelining).
- Don't set `tupleToObject` and `commandTimeout` options to `true` unless it is reasonable.
- However, `commandTimeout` has a low overhead due to the usage of `FastTimer` and is very usable in the fact that it can help you rejecting long-running requests, which may have been stale due to the network connection issue. So use this advice with caution.

## "Show me the difference"
- Here is a table which illustrates the significance of some of the possible optimization methods:

![results table of "read" benchmark](assets/read-results-table.png)
Loading