Repository navigation
v5.3.1
Reliability
- Client disconnects release their writes immediately. When a client disconnects mid-request, its request-scoped transaction is now aborted as soon as the request's
signalfires: staged writes and RocksDB write intents are released at once, and the request can no longer write through any API. Previously the orphaned transaction could hold its locks until the handler settled or the long-transaction monitor swept it (30–60 s), long enough to wedge a later conflicting commit on that worker. (#2047) - Boot replay no longer exhausts the heap. Replaying a transaction log behind a stale watermark now reads record bases without populating the record cache, so decoded records no longer pile up on the V8 heap across already-durable commits during startup. (#2988)
- Subscriptions close cleanly when a listener throws. A subscription closed with a final message is now always deregistered, even if a listener throws on that message. Before, it stayed registered and kept receiving live events. (#2948)
- UDS mirror sockets survive rolling restarts. Per-worker Unix-socket mirrors are now bound under a temporary name and renamed into place, so an outgoing HTTP worker no longer deletes its replacement's socket. Previously every
restart_service http_workers, config reload, or deploy left a fronting proxy gettingENOENTuntil the next restart. (#2964) - Local-only writes stay local on every path.
localOnlyis now honored by deletes, invalidations, relocations and publishes, and survives crash replay; previously those paths could replicate a write marked local-only. (#2902) - Node-local locks stay node-local. A
lock()call with noscopeon areplicate: falsetable now resolves to a node-local lock, so enabling replication or cluster record locks no longer turns a plugin's working lock into a 503. An explicit{ scope: 'cluster' }on such a table still fails closed. (#2903)
Backup, restore and database copies
- Restored and copied databases get a new generation.
restore_backup(online and offline), branch databases and the LMDB→RocksDB migration stamp a new database generation into the copy (RocksDB only). Live subscriptions from before the copy now end withDatabaseGenerationChangedErrorinstead of silently receiving the copy's events. (#2914) - Backup repositories can be managed without a loaded database.
list_backups,verify_backup,delete_backupandpurge_backupsnow work against the repository directory when the database is not loaded (for example after a failed restore). All Harper-managed repository mutations take a management lock, so a purge can no longer remove files from under a finalizingcreate_backup, and a delete or purge that would remove a backup a restore depends on is refused. (#2647)
Deploy
- Replicated deploys report peers that installed different code. Each node of a replicated
deploy_componentnow fingerprints what it installed, and the origin reports any peer whose source or lockfile differs. This is a report only; the deploy's status is unchanged. Localfile:sources are recorded as unidentified so they never falsely match. (#2929, #2954)
Security and TLS
- Certificate renewals publish only matching pairs. Renewing a configured certificate and private key is now coordinated across workers: the main thread watches both files and publishes only a matching cert/key pair, so a half-installed renewal keeps serving the previous certificate instead of a mismatched one. (#2989)
HTTP
- Repeated form-urlencoded fields keep all values. A repeated field now parses to an array under its own name (previously only the first value was visible), a field named
hasOwnPropertyno longer fails the request, and the form serializer no longer writes[object Object]. (#2957) - Oversized uploads get a proper 413 on the uWebSockets backend. Uploads exceeding the coarse
maxBodyBytescap now receive 413 headers before the connection closes. (#2985)
Performance
- Fewer reads per write on RocksDB.
put,patchanddeletenow read their target record once instead of twice, and inserts skip a pre-read that was discarded. (#2936, #2938) - Subscription fan-out reads a record once per update, not once per subscriber. (#2921)
Models and search
- Decision probability calibration. With a
models.calibrationblock, Harper learns a correction from persisted decisions and their later-reported outcomes, validates it on held-out decisions, and applies it to later decisions (reported ascalibrated: true; the chosen value is unchanged). (#2885) - Fulltext 0.5.0. Upgraded
@harperfast/fulltextto 0.5.0; filtered full-text search continues to use Harper's secondary indexes. (#2926)
Also in this release
whenThreadsStarted typed as a Promise again and all manageThreads exports importable by name from ES modules (#2919); test coverage for documented full-text examples and hostile-input log formatting; an LMDB test flake fix; design-note pruning; CI and review-tooling updates.
Full changelog: v5.3.0...v5.3.1