@rotorsoft/act 1.29.0 → 1.29.2
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/act.d.ts +9 -0
- package/dist/@types/act.d.ts.map +1 -1
- package/dist/@types/internal/correlate-cycle.d.ts +19 -0
- package/dist/@types/internal/correlate-cycle.d.ts.map +1 -1
- package/dist/@types/internal/settle.d.ts +1 -0
- package/dist/@types/internal/settle.d.ts.map +1 -1
- package/dist/@types/types/ports.d.ts +7 -1
- package/dist/@types/types/ports.d.ts.map +1 -1
- package/dist/index.cjs +65 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +65 -15
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1382,9 +1382,11 @@ async function run_close_cycle(targets, deps) {
|
|
|
1382
1382
|
return { truncated, skipped };
|
|
1383
1383
|
}
|
|
1384
1384
|
async function run_windowed_closes(windowed, deps, skipped) {
|
|
1385
|
+
const checkpoint = deps.reactive_events_size > 0 ? await deps.catch_up_correlation(Number.MAX_SAFE_INTEGER) : -1;
|
|
1385
1386
|
const min_at = deps.reactive_events_size > 0 ? await probe_min_watermarks(
|
|
1386
1387
|
windowed.map((t) => t.stream),
|
|
1387
|
-
deps.probe_page_size ?? SAFETY_PROBE_PAGE_SIZE
|
|
1388
|
+
deps.probe_page_size ?? SAFETY_PROBE_PAGE_SIZE,
|
|
1389
|
+
checkpoint
|
|
1388
1390
|
) : /* @__PURE__ */ new Map();
|
|
1389
1391
|
const with_lock = deps.with_stream_lock ?? ((_stream, work) => work());
|
|
1390
1392
|
const truncated = /* @__PURE__ */ new Map();
|
|
@@ -1417,7 +1419,7 @@ async function windowed_prune_pending(stream, before, max_id) {
|
|
|
1417
1419
|
);
|
|
1418
1420
|
return boundary_id !== void 0 && min_id < boundary_id;
|
|
1419
1421
|
}
|
|
1420
|
-
async function probe_min_watermarks(streams, page_size) {
|
|
1422
|
+
async function probe_min_watermarks(streams, page_size, checkpoint) {
|
|
1421
1423
|
const min_at = /* @__PURE__ */ new Map();
|
|
1422
1424
|
const source_regex = /* @__PURE__ */ new Map();
|
|
1423
1425
|
const get_regex = (source) => {
|
|
@@ -1435,11 +1437,12 @@ async function probe_min_watermarks(streams, page_size) {
|
|
|
1435
1437
|
(position) => {
|
|
1436
1438
|
last = position.stream;
|
|
1437
1439
|
const source_re = position.source ? get_regex(position.source) : void 0;
|
|
1440
|
+
const pending = position.correlated_at === void 0 || position.at < position.correlated_at;
|
|
1441
|
+
const cap = pending ? position.at : Math.max(position.at, checkpoint);
|
|
1438
1442
|
for (const stream of streams) {
|
|
1439
1443
|
if (!source_re || source_re.test(stream)) {
|
|
1440
1444
|
const prev = min_at.get(stream);
|
|
1441
|
-
if (prev === void 0 ||
|
|
1442
|
-
min_at.set(stream, position.at);
|
|
1445
|
+
if (prev === void 0 || cap < prev) min_at.set(stream, cap);
|
|
1443
1446
|
}
|
|
1444
1447
|
}
|
|
1445
1448
|
},
|
|
@@ -1609,6 +1612,17 @@ var PATTERN_CACHE_SIZE = 32;
|
|
|
1609
1612
|
var CorrelateCycle = class {
|
|
1610
1613
|
_checkpoint = -1;
|
|
1611
1614
|
_initialized = false;
|
|
1615
|
+
/**
|
|
1616
|
+
* Whether a scan might find anything. The drain has carried the same flag
|
|
1617
|
+
* since it was written — a commit raises it, an empty claim lowers it, and
|
|
1618
|
+
* a disarmed drain returns without touching the store. Correlate had no
|
|
1619
|
+
* equivalent, so a settle pass always scanned, including the final pass
|
|
1620
|
+
* whose only job is to confirm nothing changed (#1510).
|
|
1621
|
+
*
|
|
1622
|
+
* Starts armed: the log may already hold events this process has never
|
|
1623
|
+
* correlated, and only a scan can find out.
|
|
1624
|
+
*/
|
|
1625
|
+
_armed = true;
|
|
1612
1626
|
/** In-flight init, memoized for single-flight and cleared on failure. */
|
|
1613
1627
|
_init_promise;
|
|
1614
1628
|
_timer = void 0;
|
|
@@ -1672,6 +1686,14 @@ var CorrelateCycle = class {
|
|
|
1672
1686
|
get checkpoint() {
|
|
1673
1687
|
return this._checkpoint;
|
|
1674
1688
|
}
|
|
1689
|
+
/**
|
|
1690
|
+
* Signal that a commit (local or remote) may have produced events this
|
|
1691
|
+
* process has not correlated. Cheap and idempotent — the orchestrator calls
|
|
1692
|
+
* it on every commit and every notification.
|
|
1693
|
+
*/
|
|
1694
|
+
arm() {
|
|
1695
|
+
this._armed = true;
|
|
1696
|
+
}
|
|
1675
1697
|
/**
|
|
1676
1698
|
* Initialize correlation state on first call.
|
|
1677
1699
|
* - Reads the durable correlate checkpoint (and max(at)) from the store,
|
|
@@ -1757,6 +1779,13 @@ var CorrelateCycle = class {
|
|
|
1757
1779
|
*/
|
|
1758
1780
|
async correlate(query = { after: -1, limit: 10 }) {
|
|
1759
1781
|
await this.init();
|
|
1782
|
+
if (!this._armed)
|
|
1783
|
+
return {
|
|
1784
|
+
subscribed: 0,
|
|
1785
|
+
last_id: this._checkpoint,
|
|
1786
|
+
marked: 0,
|
|
1787
|
+
scanned: false
|
|
1788
|
+
};
|
|
1760
1789
|
const after = Math.max(this._checkpoint, query.after || -1);
|
|
1761
1790
|
const correlated = /* @__PURE__ */ new Map();
|
|
1762
1791
|
let last_id = after;
|
|
@@ -1817,10 +1846,11 @@ var CorrelateCycle = class {
|
|
|
1817
1846
|
lane
|
|
1818
1847
|
});
|
|
1819
1848
|
}
|
|
1820
|
-
return { subscribed, last_id, marked };
|
|
1849
|
+
return { subscribed, last_id, marked, scanned: true };
|
|
1821
1850
|
}
|
|
1822
1851
|
this._checkpoint = last_id;
|
|
1823
|
-
|
|
1852
|
+
this._armed = false;
|
|
1853
|
+
return { subscribed: 0, last_id, marked: 0, scanned: true };
|
|
1824
1854
|
}
|
|
1825
1855
|
/**
|
|
1826
1856
|
* Start a periodic correlation worker. Returns false if one is already
|
|
@@ -1831,9 +1861,14 @@ var CorrelateCycle = class {
|
|
|
1831
1861
|
if (this._timer) return false;
|
|
1832
1862
|
const limit = query.limit || 100;
|
|
1833
1863
|
this._timer = setInterval(
|
|
1834
|
-
() => this._run_scoped(
|
|
1835
|
-
|
|
1836
|
-
|
|
1864
|
+
() => this._run_scoped(() => {
|
|
1865
|
+
this.arm();
|
|
1866
|
+
return this.correlate({
|
|
1867
|
+
...query,
|
|
1868
|
+
after: this._checkpoint,
|
|
1869
|
+
limit
|
|
1870
|
+
});
|
|
1871
|
+
}).then((result) => {
|
|
1837
1872
|
if (callback && result.subscribed) callback(result.subscribed);
|
|
1838
1873
|
}).catch((err) => log().error(err)),
|
|
1839
1874
|
frequency
|
|
@@ -3119,11 +3154,11 @@ var SettleLoop = class {
|
|
|
3119
3154
|
let settled_drain;
|
|
3120
3155
|
for (let i = 0; i < maxPasses; i++) {
|
|
3121
3156
|
const after_before = this._deps.checkpoint();
|
|
3122
|
-
const { subscribed, last_id } = await this._deps.correlate({
|
|
3157
|
+
const { subscribed, last_id, scanned } = await this._deps.correlate({
|
|
3123
3158
|
...correlate_query,
|
|
3124
3159
|
after: after_before
|
|
3125
3160
|
});
|
|
3126
|
-
this._deps.breaker.passed();
|
|
3161
|
+
if (scanned) this._deps.breaker.passed();
|
|
3127
3162
|
const drain = await this._deps.drain(drain_options);
|
|
3128
3163
|
settled_drain = settled_drain ? {
|
|
3129
3164
|
fetched: [...settled_drain.fetched, ...drain.fetched],
|
|
@@ -3620,7 +3655,7 @@ var Act = class {
|
|
|
3620
3655
|
// the scoped store and `_initialized` then blocks a retry (#1191).
|
|
3621
3656
|
init: () => this._scoped(() => this._correlate.init()),
|
|
3622
3657
|
checkpoint: () => this._correlate.checkpoint,
|
|
3623
|
-
correlate: (q) => this.
|
|
3658
|
+
correlate: (q) => this._correlate_scanned(q),
|
|
3624
3659
|
drain: (o) => this.drain(o),
|
|
3625
3660
|
on_settled: (drain) => this.emit("settled", drain),
|
|
3626
3661
|
breaker: this._breaker
|
|
@@ -4033,6 +4068,7 @@ var Act = class {
|
|
|
4033
4068
|
}
|
|
4034
4069
|
/** Arm every active lane controller (ACT-1103). */
|
|
4035
4070
|
_arm_all() {
|
|
4071
|
+
this._correlate.arm();
|
|
4036
4072
|
for (const c of this._drain_controllers.values()) c.arm();
|
|
4037
4073
|
}
|
|
4038
4074
|
/**
|
|
@@ -4056,6 +4092,7 @@ var Act = class {
|
|
|
4056
4092
|
for (const lane of set) to_arm.add(lane);
|
|
4057
4093
|
}
|
|
4058
4094
|
if (to_arm.size === 0) return false;
|
|
4095
|
+
this._correlate.arm();
|
|
4059
4096
|
for (const lane of to_arm) this._drain_controllers.get(lane)?.arm();
|
|
4060
4097
|
return true;
|
|
4061
4098
|
}
|
|
@@ -4129,12 +4166,24 @@ var Act = class {
|
|
|
4129
4166
|
* @see {@link stop_correlations} to stop automatic correlation
|
|
4130
4167
|
*/
|
|
4131
4168
|
async correlate(query = { after: -1, limit: 10 }) {
|
|
4132
|
-
|
|
4169
|
+
const { subscribed, last_id } = await this._correlate_scanned(query);
|
|
4170
|
+
return { subscribed, last_id };
|
|
4171
|
+
}
|
|
4172
|
+
/**
|
|
4173
|
+
* `correlate` plus whether the pass actually read the store (#1510).
|
|
4174
|
+
*
|
|
4175
|
+
* The settle loop needs that extra bit to decide whether the pass carries a
|
|
4176
|
+
* circuit-breaker health signal, and a disarmed pass carries none. It stays
|
|
4177
|
+
* internal rather than widening the public `correlate` return, which is
|
|
4178
|
+
* charter-covered and has no use for it.
|
|
4179
|
+
*/
|
|
4180
|
+
async _correlate_scanned(query) {
|
|
4181
|
+
if (!this._drain) return { subscribed: 0, last_id: -1, scanned: false };
|
|
4133
4182
|
return this._scoped(async () => {
|
|
4134
|
-
const { subscribed, last_id, marked } = await this._correlate.correlate(query);
|
|
4183
|
+
const { subscribed, last_id, marked, scanned } = await this._correlate.correlate(query);
|
|
4135
4184
|
if ((subscribed > 0 || marked > 0) && this._reactive_events.size > 0)
|
|
4136
4185
|
this._arm_all();
|
|
4137
|
-
return { subscribed, last_id };
|
|
4186
|
+
return { subscribed, last_id, scanned };
|
|
4138
4187
|
});
|
|
4139
4188
|
}
|
|
4140
4189
|
/**
|
|
@@ -4567,6 +4616,7 @@ var Act = class {
|
|
|
4567
4616
|
async _catch_up_correlation(until) {
|
|
4568
4617
|
for (let pass = 0; pass < CLOSE_CATCH_UP_PASSES && this._correlate.checkpoint < until; pass++) {
|
|
4569
4618
|
const before = this._correlate.checkpoint;
|
|
4619
|
+
this._correlate.arm();
|
|
4570
4620
|
await this.correlate({ limit: CLOSE_CATCH_UP_LIMIT });
|
|
4571
4621
|
if (this._correlate.checkpoint <= before) break;
|
|
4572
4622
|
}
|