Repository navigation
v5.1.28
Subscriptions
-
A record key beginning with
/no longer spins every http worker holding a subscription (#2689, #2687).notifyFromTransactionData()walks a changed record's key up its/-separated ancestor hierarchy to notify subscribers at each level (resource/foo/bar→resource/foo/→resource/→ done). When the walk reached/,lastIndexOf('/', -1)clamped its from-index to 0, so the next key was/again and thedo … while (true)never progressed. Any key that reduces to/hits it:/,/foo,/some/path,//x.The loop is synchronous inside the
setImmediatenotify pass, and theNOTIFY_BATCH_SIZEyield sits outside it, so it never fires. One committedput,patch, ordeleteon such a key pegged every worker subscribed to that table at 100% CPU, with nothing logged. The main thread stayed healthy, so the Operations API kept answering while HTTP, the status endpoint, and replication served by that node were dead.The effect also propagates. The committed record sits in the node's transaction log, so once its workers recover, outbound replication delivers the record to every peer holding the same subscription and spins their workers too; a later delete of the row, including TTL expiration, re-emits the key. If you are recovering from this in a cluster, upgrade the peers before bringing the origin node's workers back.
The walk now stops when the next key equals the current one. A subscriber on the root key is still notified once, and the pass terminates. The defective walk is byte-identical in every 5.1, 5.2, and 5.3 build released before this one.
Also in this release
- Regression coverage for the key walk: the same-thread aftercommit path against a fake store, a live
Table.subscribecollection subscriber receiving a/-prefixed key through the cross-threadcommittedpath, and the/and//xroot-key shapes.DESIGN.mdrecords the termination invariant the walk must keep.
Full Changelog: v5.1.27...v5.1.28