Skip to content

Add pause resume functionality #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 26 commits into from
May 29, 2025
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
5428322
Added pause / resume functionality to zongji listener
Rentacookie May 12, 2025
f5b4ff6
Changeset
Rentacookie May 12, 2025
32d7bb5
Added typescript types declarations
Rentacookie May 13, 2025
190cfa1
Added changeset
Rentacookie May 13, 2025
c0dd696
Fixed workspace package structure
Rentacookie May 14, 2025
fae16f9
Made types package public
Rentacookie May 14, 2025
3a850f7
No default export for types package
Rentacookie May 14, 2025
ed63064
Integrated types with main package
Rentacookie May 14, 2025
ad88a60
Made project into a module
Rentacookie May 14, 2025
9b0adfe
Revert module flag
Rentacookie May 14, 2025
d7ffe63
Try declare class for Zongji class type
Rentacookie May 16, 2025
e618993
Try with export default
Rentacookie May 16, 2025
b52fdee
Try with named export
Rentacookie May 19, 2025
aa4b533
Try both named and default export
Rentacookie May 19, 2025
53329b8
Added binlog tablemap event type definition
Rentacookie May 20, 2025
e1a7d1c
Only emit table map events on table changes.
Rentacookie May 20, 2025
6feffcd
Slight adjustments to types to correctly reflect binlog event structure.
Rentacookie May 21, 2025
ec6bfa4
Cleaned up defined types, and added descriptions
Rentacookie May 22, 2025
b755c41
Added potential race condition safety net to not start the binlog str…
Rentacookie May 22, 2025
2e6288f
Added another stop check before starting the listener
Rentacookie May 26, 2025
3c56942
Don't emit errors on an already stopped listener.
Rentacookie May 26, 2025
76462dd
Exposed port configuration in types.
Rentacookie May 26, 2025
36a65a7
Don't run startup checks if listener was already stopped
Rentacookie May 27, 2025
d99e149
Updated changeset
Rentacookie May 27, 2025
c95b157
Added test
Rentacookie May 28, 2025
0804f1d
Fixed test setup
Rentacookie May 28, 2025
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
8 changes: 8 additions & 0 deletions .changeset/thick-carpets-shake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@powersync/mysql-zongji': minor
---

Added the functionality to pause / resume the zongji binlog listener
Improved stop/start functionality to better handle some race conditions
Added type definitions
The first time a TableMap event is emitted, it will always be emitted, but subsequent events will only be emitted if the table map has changed.
2 changes: 1 addition & 1 deletion .github/workflows/dev-packages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
- uses: pnpm/action-setup@v2
- uses: pnpm/action-setup@v4
name: Install pnpm
with:
version: 9
Expand Down
6 changes: 2 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,14 @@ jobs:
-e MYSQL_ROOT_PASSWORD=my_password \
-p 3306:3306 \
-d mysql:${{ matrix.mysql-version }} \
--server-id=1 \
--log-bin=/var/lib/mysql/mysql-bin.log \
--binlog-format=row
--log-bin=/var/lib/mysql/mysql-bin.log
- name: Setup NodeJS
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'

- uses: pnpm/action-setup@v2
- uses: pnpm/action-setup@v4
name: Install pnpm
with:
version: 9
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v20.12.2
v22.14.0
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,9 @@ Neither method requires any arguments.

## Run Tests

- install [Docker](https://www.docker.com/community-edition#download)
- run `docker-compose up` and then `./docker-test.sh`
- Install [Docker](https://www.docker.com/community-edition#download)
- Run `docker-compose up` and then `./docker-test.sh`
- Some tests can be run directly, but some of the types.js tests pertaining to dates are affected by the host's timezone and are consequently brittle.

## References

Expand All @@ -157,7 +158,7 @@ The following resources provided valuable information that greatly assisted in c
- https://kkaefer.com/node-cpp-modules/
- https://dev.mysql.com/doc/internals/en/replication-protocol.html
- https://web.archive.org/web/20200201195450/https://www.cs.wichita.edu/~chang/lecture/cs742/program/how-mysql-c-api.html
- https://github.com/jeremycole/mysql_binlog (Ruby implemenation of MySQL binlog parser)
- https://github.com/jeremycole/mysql_binlog (Ruby implementation of MySQL binlog parser)
- https://dev.mysql.com/doc/internals/en/date-and-time-data-type-representation.html

## License
Expand Down
2 changes: 1 addition & 1 deletion docker-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
MYSQL_HOSTS="mysql80 mysql84"

for hostname in ${MYSQL_HOSTS}; do
echo $hostname + node 20
echo $hostname + node 22
docker run -it --network=powersync-mysql-zongji_default -e MYSQL_HOST=$hostname -w /build -v $PWD:/build node:20 npm test
done
47 changes: 33 additions & 14 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ function ZongJi(dsn) {
this.ctrlCallbacks = [];
this.tableMap = {};
this.ready = false;
this.stopped = false;
this.useChecksum = false;

this._establishConnection(dsn);
Expand Down Expand Up @@ -192,6 +193,9 @@ ZongJi.prototype.start = function (options = {}) {
this._filters(options);

const testChecksum = (resolve, reject) => {
if (this.stopped) {
resolve();
}
this._isChecksumEnabled((err, checksumEnabled) => {
if (err) {
reject(err);
Expand All @@ -203,6 +207,9 @@ ZongJi.prototype.start = function (options = {}) {
};

const findBinlogEnd = (resolve, reject) => {
if (this.stopped) {
resolve();
}
this._findBinlogEnd((err, result) => {
if (err) {
return reject(err);
Expand Down Expand Up @@ -240,9 +247,8 @@ ZongJi.prototype.start = function (options = {}) {
this.emit('binlog', event);
this.connection.resume();
});
return;
}
break;
return;
}
case 'Rotate':
if (this.options.filename !== event.binlogName) {
Expand All @@ -263,25 +269,37 @@ ZongJi.prototype.start = function (options = {}) {
Promise.all(promises)
.then(() => {
this.BinlogClass = initBinlogClass(this);
this.ready = true;
this.emit('ready');

this.connection._protocol._enqueue(new this.BinlogClass(binlogHandler));
if (!this.stopped) {
this.connection._protocol._enqueue(new this.BinlogClass(binlogHandler));
this.ready = true;
this.emit('ready');
}
})
.catch((err) => {
this.emit('error', err);
});
};

ZongJi.prototype.stop = function () {
// Binary log connection does not end with destroy()
this.connection.destroy();
this.ctrlConnection.query('KILL ' + this.connection.threadId, () => {
if (this.ctrlConnectionOwner) {
this.ctrlConnection.destroy();
}
this.emit('stopped');
});
if (!this.stopped) {
this.stopped = true;
// Binary log connection does not end with destroy()
this.connection.destroy();
this.ctrlConnection.query('KILL ' + this.connection.threadId, (err, result) => {
if (this.ctrlConnectionOwner) {
this.ctrlConnection.destroy();
}
this.emit('stopped');
});
}
};

ZongJi.prototype.pause = function () {
this.connection.pause();
};

ZongJi.prototype.resume = function () {
this.connection.resume();
};

// It includes every events by default.
Expand Down Expand Up @@ -312,3 +330,4 @@ ZongJi.prototype._skipSchema = function (database, table) {
};

module.exports = ZongJi;
module.exports.ZongJi = ZongJi;
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "0.1.0",
"description": "A MySQL 8.0 >= compatible fork of ZongJi - a MySQL binlog listener for Node.js.",
"main": "index.js",
"types": "types/index.d.ts",
"directories": {
"test": "test"
},
Expand Down Expand Up @@ -35,15 +36,15 @@
],
"license": "MIT",
"engines": {
"node": ">=20.0.0"
"node": ">=22.0.0"
},
"devDependencies": {
"@changesets/cli": "^2.27.3",
"prettier": "^2.8.8",
"@changesets/cli": "^2.29.4",
"prettier": "^3.5.3",
"tap": "^21.0.1"
},
"dependencies": {
"big-integer": "1.6.51",
"big-integer": "1.6.52",
"iconv-lite": "0.6.3",
"@vlasky/mysql": "^2.18.6"
}
Expand Down
Loading