@rotorsoft/act 1.32.5 → 1.32.6
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 +3 -3
- package/dist/@types/internal/close-cycle.d.ts +7 -3
- package/dist/@types/internal/close-cycle.d.ts.map +1 -1
- package/dist/index.cjs +38 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +38 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1070,6 +1070,23 @@ async function run_close_cycle(targets, deps) {
|
|
|
1070
1070
|
const skipped = [];
|
|
1071
1071
|
const windowed_result = windowed.length ? await run_windowed_closes(windowed, deps, skipped) : /* @__PURE__ */ new Map();
|
|
1072
1072
|
if (!full.length) return { truncated: windowed_result, skipped };
|
|
1073
|
+
const truncated = await with_stream_locks(
|
|
1074
|
+
full.map((t) => t.stream),
|
|
1075
|
+
deps,
|
|
1076
|
+
() => run_full_closes(full, target_map, deps, skipped)
|
|
1077
|
+
);
|
|
1078
|
+
for (const [stream, entry] of windowed_result) truncated.set(stream, entry);
|
|
1079
|
+
return { truncated, skipped };
|
|
1080
|
+
}
|
|
1081
|
+
function with_stream_locks(streams, deps, work) {
|
|
1082
|
+
const with_lock = deps.with_stream_lock ?? ((_stream, w) => w());
|
|
1083
|
+
return [...streams].sort().reduceRight(
|
|
1084
|
+
(inner, stream) => () => with_lock(stream, inner),
|
|
1085
|
+
work
|
|
1086
|
+
)();
|
|
1087
|
+
}
|
|
1088
|
+
async function run_full_closes(full, target_map, deps, skipped) {
|
|
1089
|
+
const none = /* @__PURE__ */ new Map();
|
|
1073
1090
|
const streams = full.map((t) => t.stream);
|
|
1074
1091
|
const stream_info = await scan_stream_heads(streams);
|
|
1075
1092
|
for (const target of full) {
|
|
@@ -1092,7 +1109,7 @@ async function run_close_cycle(targets, deps) {
|
|
|
1092
1109
|
deps.probe_page_size ?? SAFETY_PROBE_PAGE_SIZE,
|
|
1093
1110
|
deps.catch_up_correlation
|
|
1094
1111
|
);
|
|
1095
|
-
if (!safe.length) return
|
|
1112
|
+
if (!safe.length) return none;
|
|
1096
1113
|
const { guarded, guard_events } = await guard_with_tombstones(
|
|
1097
1114
|
safe,
|
|
1098
1115
|
stream_info,
|
|
@@ -1100,7 +1117,7 @@ async function run_close_cycle(targets, deps) {
|
|
|
1100
1117
|
deps.tombstone,
|
|
1101
1118
|
skipped
|
|
1102
1119
|
);
|
|
1103
|
-
if (!guarded.length) return
|
|
1120
|
+
if (!guarded.length) return none;
|
|
1104
1121
|
const seed_states = await load_restart_seeds(
|
|
1105
1122
|
guarded,
|
|
1106
1123
|
target_map,
|
|
@@ -1110,14 +1127,18 @@ async function run_close_cycle(targets, deps) {
|
|
|
1110
1127
|
deps.logger
|
|
1111
1128
|
);
|
|
1112
1129
|
await run_archive_callbacks(guarded, target_map);
|
|
1113
|
-
const
|
|
1130
|
+
const still_guarded = await heads_still_guarded(
|
|
1114
1131
|
guarded,
|
|
1132
|
+
guard_events,
|
|
1133
|
+
skipped
|
|
1134
|
+
);
|
|
1135
|
+
if (!still_guarded.length) return none;
|
|
1136
|
+
return truncate_and_warm_cache(
|
|
1137
|
+
still_guarded,
|
|
1115
1138
|
seed_states,
|
|
1116
1139
|
guard_events,
|
|
1117
1140
|
deps.correlation
|
|
1118
1141
|
);
|
|
1119
|
-
for (const [stream, entry] of windowed_result) truncated.set(stream, entry);
|
|
1120
|
-
return { truncated, skipped };
|
|
1121
1142
|
}
|
|
1122
1143
|
async function run_windowed_closes(windowed, deps, skipped) {
|
|
1123
1144
|
const checkpoint = deps.reactive_events_size > 0 ? await deps.catch_up_correlation(Number.MAX_SAFE_INTEGER) : -1;
|
|
@@ -1307,6 +1328,15 @@ async function run_archive_callbacks(guarded, target_map) {
|
|
|
1307
1328
|
if (archive_fn) await archive_fn();
|
|
1308
1329
|
}
|
|
1309
1330
|
}
|
|
1331
|
+
async function heads_still_guarded(guarded, guard_events, skipped) {
|
|
1332
|
+
const heads = await store().query_stats(guarded, {});
|
|
1333
|
+
return guarded.filter((stream) => {
|
|
1334
|
+
if (heads.get(stream)?.head.id === guard_events.get(stream).id)
|
|
1335
|
+
return true;
|
|
1336
|
+
skipped.push(stream);
|
|
1337
|
+
return false;
|
|
1338
|
+
});
|
|
1339
|
+
}
|
|
1310
1340
|
async function truncate_and_warm_cache(guarded, seed_states, guard_events, correlation) {
|
|
1311
1341
|
const trunc_targets = guarded.map((stream) => {
|
|
1312
1342
|
const snapshot = seed_states.get(stream);
|
|
@@ -3581,9 +3611,9 @@ var Act = class {
|
|
|
3581
3611
|
*/
|
|
3582
3612
|
_close_locks = /* @__PURE__ */ new Map();
|
|
3583
3613
|
/**
|
|
3584
|
-
* Run `work` under the per-stream close lock (#1222). Serializes
|
|
3585
|
-
*
|
|
3586
|
-
* different streams proceed in parallel.
|
|
3614
|
+
* Run `work` under the per-stream close lock (#1222). Serializes close
|
|
3615
|
+
* critical sections for the same stream (windowed prunes, and full closes
|
|
3616
|
+
* since #1738) while letting different streams proceed in parallel.
|
|
3587
3617
|
*/
|
|
3588
3618
|
_with_close_lock(stream, work) {
|
|
3589
3619
|
const prev = this._close_locks.get(stream) ?? Promise.resolve();
|