| Filename | Latest commit message | Latest commit date |
|---|---|---|
A merge wrote each inserted row one by one: a savepoint for the domain row, another for its tracker, two statements each, and then read every tracker back to record attempted values. A device's first push of a library of 8,000 cards (24,650 changes) took the server 34 to 37 s, nearly all of it in those round trips. A batch the projection pass leaves out (nothing in it touches a foreign key or a unique index, or its inserts are proven to change no decision) now writes its new rows many to a statement, up to 1,000 at a time, in one savepoint: each table's domain rows in one insert, parents' tables first, then their trackers. A row qualifies when the batch inserts it once and touches it no other way, no tracker exists for it, nothing earlier in the batch names it, and every row of the batch it names was written before it. Its values are planned in the batch's order, as the per-row path plans them. A chunk whose writes fail (a row there already, perhaps another space's) is rolled back, the presence it claimed for its rows is forgotten, and it and every row after it are left to the per-row path, which tells those cases apart. Attempted values read the trackers the merge holds instead of querying them. The proof for merged inserts also accepts a parent of the row's own table inserted earlier in the batch, so a library's nested studysets no longer send its first push through the pass; a chunk ends before a row whose parent of its own table it holds. A row naming itself, or a parent inserted after it, still takes the pass. Measured on PostgreSQL, the 24,650 changes merge in about 5 s instead of 34 to 37 s, and with the studysets nested instead of 41 s. A device on SQLite, whose adapter still inserts row by row, receives the library in 44 s instead of 60 s. The new tests cover a batch spanning chunks, a chunk failing on a row whose tracker was lost and falling back, and a tree of one table's rows inserted parents first (the shortcut, a chunk per level) and children first (the pass). The core, server, integration and simulation suites pass, but for two PostgreSQL tests that can't start their database while another embedded PostgreSQL runs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
| .. | ||
| .test_databases | ||
| bin | ||
| config | ||
| lib | ||
| migrations | ||
| test | ||
| .gitignore | ||
| analysis_options.yaml | ||
| CHANGELOG.md | ||
| dart_test.yaml | ||
| pubspec.yaml | ||
| README.md | ||
serverpod_offline_sync_test_server
This is the starting point for your Serverpod server.
To run your server, you first need to start Postgres and Redis. It's easiest to do with Docker.
docker compose up --build --detach
Then you can start the Serverpod server.
dart bin/main.dart
When you are finished, you can shut down Serverpod with Ctrl-C, then stop Postgres and Redis.
docker compose stop