@rotorsoft/act-pg 1.17.0 → 1.18.0
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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/@types/postgres-store.d.ts.map +1 -1
- package/dist/index.cjs +51 -55
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +51 -55
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -393,6 +393,11 @@ var PostgresStore = class {
|
|
|
393
393
|
ON ${this._fqs} (lane, priority DESC, at)
|
|
394
394
|
WHERE blocked = false AND at < correlated_at;`
|
|
395
395
|
);
|
|
396
|
+
await client.query(
|
|
397
|
+
`CREATE INDEX IF NOT EXISTS "${this.config.table}_streams_at_ix"
|
|
398
|
+
ON ${this._fqs} (at)
|
|
399
|
+
WHERE blocked = false AND at < correlated_at;`
|
|
400
|
+
);
|
|
396
401
|
await client.query("COMMIT");
|
|
397
402
|
logger.info(
|
|
398
403
|
`Seeded schema "${this.config.schema}" with table "${this.config.table}"`
|
|
@@ -661,67 +666,64 @@ var PostgresStore = class {
|
|
|
661
666
|
-- cost O(subscribed streams) per claim per worker no matter how
|
|
662
667
|
-- little work was pending.
|
|
663
668
|
--
|
|
664
|
-
--
|
|
665
|
-
--
|
|
666
|
-
--
|
|
667
|
-
--
|
|
668
|
-
--
|
|
669
|
-
--
|
|
670
|
-
--
|
|
671
|
-
--
|
|
669
|
+
-- The predicate is repeated in each arm below rather than factored
|
|
670
|
+
-- into a shared CTE, and that repetition is load-bearing (#1510). A
|
|
671
|
+
-- CTE referenced more than once is materialized, so LIMIT 8 was
|
|
672
|
+
-- applied to a fully-built 100,000-row result instead of pushing into
|
|
673
|
+
-- the index: measured at 75.6 ms for a claim that returns 8 rows.
|
|
674
|
+
-- Reading the base table in each arm lets the planner stop after the
|
|
675
|
+
-- limit \u2014 19.9 ms with the existing index, 2.0 ms once the
|
|
676
|
+
-- at-ordered partial index below serves the two watermark arms.
|
|
677
|
+
--
|
|
678
|
+
-- A row with no mark compares unknown and is excluded by SQL's own
|
|
679
|
+
-- rules. That is definitional (#1446): a subscription is claimable iff
|
|
680
|
+
-- a mark says so. seed() marks rows that predate the column.
|
|
681
|
+
--
|
|
682
|
+
-- Priority lanes (ACT-102): higher priority first, then
|
|
683
|
+
-- lagging-watermark order. With everyone at priority=0 the ORDER BY
|
|
684
|
+
-- collapses to plain at ASC, so existing workloads see no change.
|
|
672
685
|
--
|
|
673
|
-
-- The
|
|
674
|
-
--
|
|
675
|
-
--
|
|
676
|
-
--
|
|
677
|
-
--
|
|
678
|
-
--
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
SELECT stream, source, at, priority, lane
|
|
686
|
+
-- The lagging frontier is a UNION of two portions (ACT-1223): the
|
|
687
|
+
-- priority portion takes the first (lagging - fair) slots by
|
|
688
|
+
-- priority DESC, at ASC; a fairness reserve then fills fair more
|
|
689
|
+
-- by pure at ASC (priority ignored), excluding the ones already
|
|
690
|
+
-- chosen, so a default-priority lagging stream is never starved out
|
|
691
|
+
-- by sustained higher-priority load.
|
|
692
|
+
prio AS (
|
|
693
|
+
SELECT stream, source, at, lane, TRUE AS lagging
|
|
682
694
|
FROM ${this._fqs} s
|
|
683
695
|
WHERE s.blocked = false
|
|
684
696
|
AND s.at < s.correlated_at
|
|
685
697
|
${lane_clause}
|
|
686
698
|
AND (s.leased_by IS NULL OR s.leased_until <= NOW())
|
|
687
699
|
AND (s.deferred_at IS NULL OR s.deferred_at <= NOW())
|
|
700
|
+
ORDER BY s.priority DESC, s.at ASC
|
|
701
|
+
LIMIT ($1::int - $5::int)
|
|
702
|
+
),
|
|
703
|
+
fair AS (
|
|
704
|
+
SELECT stream, source, at, lane, TRUE AS lagging
|
|
705
|
+
FROM ${this._fqs} s
|
|
706
|
+
WHERE s.blocked = false
|
|
707
|
+
AND s.at < s.correlated_at
|
|
708
|
+
${lane_clause}
|
|
709
|
+
AND (s.leased_by IS NULL OR s.leased_until <= NOW())
|
|
710
|
+
AND (s.deferred_at IS NULL OR s.deferred_at <= NOW())
|
|
711
|
+
AND s.stream NOT IN (SELECT stream FROM prio)
|
|
712
|
+
ORDER BY s.at ASC
|
|
713
|
+
LIMIT $5
|
|
688
714
|
),
|
|
689
|
-
-- Priority lanes (ACT-102): higher priority first, then
|
|
690
|
-
-- lagging-watermark order. With everyone at priority=0 the
|
|
691
|
-
-- ORDER BY collapses to plain at ASC so existing workloads
|
|
692
|
-
-- see no behavior change.
|
|
693
|
-
--
|
|
694
|
-
-- The lagging frontier is a UNION of two portions (ACT-1223): the
|
|
695
|
-
-- priority-ordered portion takes the first (lagging - fair) slots
|
|
696
|
-
-- by priority DESC, at ASC; a fairness reserve then fills fair more
|
|
697
|
-
-- slots by pure at ASC (priority ignored), excluding the ones
|
|
698
|
-
-- already chosen, so a default-priority lagging stream is never
|
|
699
|
-
-- starved out by sustained higher-priority load. With all
|
|
700
|
-
-- priorities equal both portions order by at, a no-op merge.
|
|
701
715
|
lag AS (
|
|
702
|
-
|
|
703
|
-
SELECT stream, source, at, lane, TRUE AS lagging
|
|
704
|
-
FROM available
|
|
705
|
-
ORDER BY priority DESC, at ASC
|
|
706
|
-
LIMIT ($1::int - $5::int)
|
|
707
|
-
)
|
|
708
|
-
UNION
|
|
709
|
-
(
|
|
710
|
-
SELECT stream, source, at, lane, TRUE AS lagging
|
|
711
|
-
FROM available
|
|
712
|
-
WHERE stream NOT IN (
|
|
713
|
-
SELECT stream FROM available
|
|
714
|
-
ORDER BY priority DESC, at ASC
|
|
715
|
-
LIMIT ($1::int - $5::int)
|
|
716
|
-
)
|
|
717
|
-
ORDER BY at ASC
|
|
718
|
-
LIMIT $5
|
|
719
|
-
)
|
|
716
|
+
SELECT * FROM prio UNION SELECT * FROM fair
|
|
720
717
|
),
|
|
721
718
|
lead AS (
|
|
722
719
|
SELECT stream, source, at, lane, FALSE AS lagging
|
|
723
|
-
FROM
|
|
724
|
-
|
|
720
|
+
FROM ${this._fqs} s
|
|
721
|
+
WHERE s.blocked = false
|
|
722
|
+
AND s.at < s.correlated_at
|
|
723
|
+
${lane_clause}
|
|
724
|
+
AND (s.leased_by IS NULL OR s.leased_until <= NOW())
|
|
725
|
+
AND (s.deferred_at IS NULL OR s.deferred_at <= NOW())
|
|
726
|
+
ORDER BY s.at DESC
|
|
725
727
|
LIMIT $2
|
|
726
728
|
),
|
|
727
729
|
combined AS (
|
|
@@ -1503,12 +1505,6 @@ var PostgresStore = class {
|
|
|
1503
1505
|
this._fqt
|
|
1504
1506
|
]);
|
|
1505
1507
|
const result = /* @__PURE__ */ new Map();
|
|
1506
|
-
const retired = full.filter((t) => t.snapshot === void 0).map((t) => t.stream);
|
|
1507
|
-
if (retired.length) {
|
|
1508
|
-
await client.query(`DELETE FROM ${this._fqs} WHERE stream = ANY($1)`, [
|
|
1509
|
-
retired
|
|
1510
|
-
]);
|
|
1511
|
-
}
|
|
1512
1508
|
for (const { stream, snapshot, meta } of full) {
|
|
1513
1509
|
const { rowCount } = await client.query(
|
|
1514
1510
|
`DELETE FROM ${this._fqt} WHERE stream = $1`,
|