@rotorsoft/act-pg 1.16.1 → 1.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"postgres-store.d.ts","sourceRoot":"","sources":["../../src/postgres-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"postgres-store.d.ts","sourceRoot":"","sources":["../../src/postgres-store.ts"],"names":[],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -40,7 +40,6 @@ var import_act = require("@rotorsoft/act");
40
40
  var import_act_crypto = require("@rotorsoft/act-crypto");
41
41
  var import_pg = __toESM(require("pg"), 1);
42
42
  var logger = (0, import_act.log)();
43
- var SOURCE_METACHARACTER_CLASS = "[]^$.*+?()[{}|\\\\]";
44
43
  var { Pool, types } = import_pg.default;
45
44
  var JSONB_OID = types.builtins.JSONB;
46
45
  var scopedTypes = {
@@ -360,6 +359,11 @@ var PostgresStore = class {
360
359
  `ALTER TABLE ${this._fqs}
361
360
  ADD COLUMN IF NOT EXISTS correlated_at int;`
362
361
  );
362
+ await client.query(
363
+ `UPDATE ${this._fqs}
364
+ SET correlated_at = (SELECT COALESCE(MAX(id), -1) FROM ${this._fqt})
365
+ WHERE correlated_at IS NULL;`
366
+ );
363
367
  await client.query(
364
368
  `DO $$
365
369
  BEGIN
@@ -413,6 +417,11 @@ var PostgresStore = class {
413
417
  ON ${this._fqs} (lane, priority DESC, at)
414
418
  WHERE blocked = false AND at < correlated_at;`
415
419
  );
420
+ await client.query(
421
+ `CREATE INDEX IF NOT EXISTS "${this.config.table}_streams_at_ix"
422
+ ON ${this._fqs} (at)
423
+ WHERE blocked = false AND at < correlated_at;`
424
+ );
416
425
  await client.query("COMMIT");
417
426
  logger.info(
418
427
  `Seeded schema "${this.config.schema}" with table "${this.config.table}"`
@@ -672,129 +681,73 @@ var PostgresStore = class {
672
681
  -- and lock EVERY claimable stream for this transaction, starving
673
682
  -- overlapping competing consumers. We only lock the small
674
683
  -- lagging+leading candidate slice, down in the "locked" CTE.
675
- -- Eligibility, split by SOURCE CLASS rather than expressed as one
676
- -- disjunction (#1448). The three classes are mutually exclusive, so
677
- -- the UNION ALL returns exactly what the old OR-chain did \u2014 but each
678
- -- arm now carries a single, planner-legible predicate.
679
684
  --
680
- -- That matters for one arm in particular. Written as
681
- -- "s.source IS NULL OR (... AND e.stream = s.source) OR (... ~ ...)",
682
- -- the equality is buried inside a disjunction and is NOT sargable:
683
- -- no index on (stream, id) can serve it, so every probe degenerated
684
- -- into a forward scan of the pk from the stream's watermark. With
685
- -- the classes separated, the literal arm \u2014 every per-aggregate
686
- -- .to(e => ({target: e.stream})) reaction, i.e. the overwhelming
687
- -- majority \u2014 becomes an index seek on (stream, id).
685
+ -- Eligibility is a pure subscription-table predicate (#1488).
686
+ -- claim does not read the event log at all: correlate marks the
687
+ -- highest event id that resolves to a target, and at <
688
+ -- correlated_at is the whole question. The probe this replaced ran
689
+ -- an EXISTS against the events table once per eligible row, which
690
+ -- cost O(subscribed streams) per claim per worker no matter how
691
+ -- little work was pending.
692
+ --
693
+ -- The predicate is repeated in each arm below rather than factored
694
+ -- into a shared CTE, and that repetition is load-bearing (#1510). A
695
+ -- CTE referenced more than once is materialized, so LIMIT 8 was
696
+ -- applied to a fully-built 100,000-row result instead of pushing into
697
+ -- the index: measured at 75.6 ms for a claim that returns 8 rows.
698
+ -- Reading the base table in each arm lets the planner stop after the
699
+ -- limit \u2014 19.9 ms with the existing index, 2.0 ms once the
700
+ -- at-ordered partial index below serves the two watermark arms.
688
701
  --
689
- -- Measured at 10k subscribed streams with 10 pending: 5,792 ms
690
- -- before, 10.3 ms after. See libs/act-pg/PERFORMANCE.md for #1448.
691
- eligible AS (
692
- SELECT stream, source, at, priority, lane, correlated_at
702
+ -- A row with no mark compares unknown and is excluded by SQL's own
703
+ -- rules. That is definitional (#1446): a subscription is claimable iff
704
+ -- a mark says so. seed() marks rows that predate the column.
705
+ --
706
+ -- Priority lanes (ACT-102): higher priority first, then
707
+ -- lagging-watermark order. With everyone at priority=0 the ORDER BY
708
+ -- collapses to plain at ASC, so existing workloads see no change.
709
+ --
710
+ -- The lagging frontier is a UNION of two portions (ACT-1223): the
711
+ -- priority portion takes the first (lagging - fair) slots by
712
+ -- priority DESC, at ASC; a fairness reserve then fills fair more
713
+ -- by pure at ASC (priority ignored), excluding the ones already
714
+ -- chosen, so a default-priority lagging stream is never starved out
715
+ -- by sustained higher-priority load.
716
+ prio AS (
717
+ SELECT stream, source, at, lane, TRUE AS lagging
693
718
  FROM ${this._fqs} s
694
- WHERE blocked = false
719
+ WHERE s.blocked = false
720
+ AND s.at < s.correlated_at
695
721
  ${lane_clause}
696
- AND (leased_by IS NULL OR leased_until <= NOW())
697
- AND (deferred_at IS NULL OR deferred_at <= NOW())
722
+ AND (s.leased_by IS NULL OR s.leased_until <= NOW())
723
+ AND (s.deferred_at IS NULL OR s.deferred_at <= NOW())
724
+ ORDER BY s.priority DESC, s.at ASC
725
+ LIMIT ($1::int - $5::int)
698
726
  ),
699
- available AS (
700
- -- Fast arm (#1485): a marked stream answers from the subscription
701
- -- row alone. Read from the base table, NOT from the eligible CTE:
702
- -- it is referenced several times so PG materializes it, and a
703
- -- materialized scan cannot use the partial index this predicate was
704
- -- built for (WHERE blocked = false AND at < correlated_at).
705
- -- The comparison is NULL-safe: an unmarked row compares
706
- -- unknown and is excluded here, falling through to the legacy arms.
707
- SELECT stream, source, at, priority, lane
727
+ fair AS (
728
+ SELECT stream, source, at, lane, TRUE AS lagging
708
729
  FROM ${this._fqs} s
709
730
  WHERE s.blocked = false
710
731
  AND s.at < s.correlated_at
711
732
  ${lane_clause}
712
733
  AND (s.leased_by IS NULL OR s.leased_until <= NOW())
713
734
  AND (s.deferred_at IS NULL OR s.deferred_at <= NOW())
714
- UNION ALL
715
- -- Legacy arms, gated on an absent mark. NULL means "unknown", so
716
- -- an install that predates the column probes the event log exactly
717
- -- as it did before, and each row migrates to the fast arm the first
718
- -- time correlate marks it. Deleted once correlate marks universally.
719
- --
720
- -- Every arm below is watermark-agnostic (#1446): a fresh
721
- -- subscription sits at -1, and e.id > s.at already answers
722
- -- correctly there, since the first event has a greater id.
723
- -- There used to be a fourth arm claiming at < 0 unconditionally,
724
- -- which handed out an empty lease and a no-op ack for every
725
- -- subscription with no matching events yet.
726
- -- Source-less subscription: any non-snapshot event past the
727
- -- watermark counts, so the id index alone answers it.
728
- SELECT stream, source, at, priority, lane FROM eligible s
729
- WHERE s.correlated_at IS NULL
730
- AND s.source IS NULL
731
- AND EXISTS (
732
- SELECT 1 FROM ${this._fqt} e
733
- WHERE e.id > s.at AND e.name <> '${import_act.SNAP_EVENT}' LIMIT 1
734
- )
735
- UNION ALL
736
- -- Literal source (no regex metacharacter): exact equality, so
737
- -- "s1" never claims "s12", and (stream, id) is usable.
738
- SELECT stream, source, at, priority, lane FROM eligible s
739
- WHERE s.correlated_at IS NULL
740
- AND s.source IS NOT NULL
741
- AND s.source !~ '${SOURCE_METACHARACTER_CLASS}'
742
- AND EXISTS (
743
- SELECT 1 FROM ${this._fqt} e
744
- WHERE e.stream = s.source AND e.id > s.at
745
- AND e.name <> '${import_act.SNAP_EVENT}' LIMIT 1
746
- )
747
- UNION ALL
748
- -- Pattern source (e.g. '^(A|B)$'): POSIX match, so the
749
- -- calculator's static regex reaction is claimed for every stream
750
- -- it anchors. Unavoidably a scan \u2014 but only for the subscriptions
751
- -- that actually declare a pattern.
752
- SELECT stream, source, at, priority, lane FROM eligible s
753
- WHERE s.correlated_at IS NULL
754
- AND s.source IS NOT NULL
755
- AND s.source ~ '${SOURCE_METACHARACTER_CLASS}'
756
- AND EXISTS (
757
- SELECT 1 FROM ${this._fqt} e
758
- WHERE e.id > s.at AND e.name <> '${import_act.SNAP_EVENT}'
759
- AND e.stream ~ s.source LIMIT 1
760
- )
735
+ AND s.stream NOT IN (SELECT stream FROM prio)
736
+ ORDER BY s.at ASC
737
+ LIMIT $5
761
738
  ),
762
- -- Priority lanes (ACT-102): higher priority first, then
763
- -- lagging-watermark order. With everyone at priority=0 the
764
- -- ORDER BY collapses to plain at ASC so existing workloads
765
- -- see no behavior change.
766
- --
767
- -- The lagging frontier is a UNION of two portions (ACT-1223): the
768
- -- priority-ordered portion takes the first (lagging - fair) slots
769
- -- by priority DESC, at ASC; a fairness reserve then fills fair more
770
- -- slots by pure at ASC (priority ignored), excluding the ones
771
- -- already chosen, so a default-priority lagging stream is never
772
- -- starved out by sustained higher-priority load. With all
773
- -- priorities equal both portions order by at, a no-op merge.
774
739
  lag AS (
775
- (
776
- SELECT stream, source, at, lane, TRUE AS lagging
777
- FROM available
778
- ORDER BY priority DESC, at ASC
779
- LIMIT ($1::int - $5::int)
780
- )
781
- UNION
782
- (
783
- SELECT stream, source, at, lane, TRUE AS lagging
784
- FROM available
785
- WHERE stream NOT IN (
786
- SELECT stream FROM available
787
- ORDER BY priority DESC, at ASC
788
- LIMIT ($1::int - $5::int)
789
- )
790
- ORDER BY at ASC
791
- LIMIT $5
792
- )
740
+ SELECT * FROM prio UNION SELECT * FROM fair
793
741
  ),
794
742
  lead AS (
795
743
  SELECT stream, source, at, lane, FALSE AS lagging
796
- FROM available
797
- ORDER BY at DESC
744
+ FROM ${this._fqs} s
745
+ WHERE s.blocked = false
746
+ AND s.at < s.correlated_at
747
+ ${lane_clause}
748
+ AND (s.leased_by IS NULL OR s.leased_until <= NOW())
749
+ AND (s.deferred_at IS NULL OR s.deferred_at <= NOW())
750
+ ORDER BY s.at DESC
798
751
  LIMIT $2
799
752
  ),
800
753
  combined AS (