@rotorsoft/act 0.6.2 → 0.6.4
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/README.md +36 -3
- package/dist/.tsbuildinfo +1 -1
- package/dist/@types/act.d.ts +1 -0
- package/dist/@types/act.d.ts.map +1 -1
- package/dist/@types/adapters/InMemoryStore.d.ts +3 -0
- package/dist/@types/adapters/InMemoryStore.d.ts.map +1 -1
- package/dist/@types/types/reaction.d.ts +9 -3
- package/dist/@types/types/reaction.d.ts.map +1 -1
- package/dist/index.cjs +59 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +59 -32
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -215,53 +215,54 @@ var InMemoryStream = class {
|
|
|
215
215
|
}
|
|
216
216
|
/**
|
|
217
217
|
* Attempt to lease this stream for processing.
|
|
218
|
-
* @param
|
|
219
|
-
* @param by - The lease holder.
|
|
218
|
+
* @param lease - The lease request.
|
|
220
219
|
* @param millis - Lease duration in milliseconds.
|
|
221
220
|
* @returns The granted lease or undefined if blocked.
|
|
222
221
|
*/
|
|
223
|
-
lease(
|
|
222
|
+
lease(lease, millis) {
|
|
224
223
|
if (this.is_avaliable) {
|
|
225
224
|
if (millis > 0) {
|
|
226
|
-
this._leased_by = by;
|
|
225
|
+
this._leased_by = lease.by;
|
|
227
226
|
this._leased_until = new Date(Date.now() + millis);
|
|
228
227
|
this._retry = this._retry + 1;
|
|
229
228
|
}
|
|
230
229
|
return {
|
|
231
230
|
stream: this.stream,
|
|
232
231
|
source: this.source,
|
|
233
|
-
at,
|
|
234
|
-
by,
|
|
235
|
-
retry: this._retry
|
|
232
|
+
at: lease.at,
|
|
233
|
+
by: lease.by,
|
|
234
|
+
retry: this._retry,
|
|
235
|
+
lagging: lease.lagging
|
|
236
236
|
};
|
|
237
237
|
}
|
|
238
238
|
}
|
|
239
239
|
/**
|
|
240
240
|
* Acknowledge completion of processing for this stream.
|
|
241
|
-
* @param
|
|
242
|
-
* @param by - Lease holder that processed the watermark.
|
|
241
|
+
* @param lease - The lease request.
|
|
243
242
|
*/
|
|
244
|
-
ack(
|
|
245
|
-
if (this._leased_by === by) {
|
|
243
|
+
ack(lease) {
|
|
244
|
+
if (this._leased_by === lease.by) {
|
|
246
245
|
this._leased_by = void 0;
|
|
247
246
|
this._leased_until = void 0;
|
|
248
|
-
this._at = at;
|
|
247
|
+
this._at = lease.at;
|
|
249
248
|
this._retry = -1;
|
|
250
249
|
return {
|
|
251
250
|
stream: this.stream,
|
|
252
251
|
source: this.source,
|
|
253
252
|
at: this._at,
|
|
254
|
-
by,
|
|
255
|
-
retry: this._retry
|
|
253
|
+
by: lease.by,
|
|
254
|
+
retry: this._retry,
|
|
255
|
+
lagging: lease.lagging
|
|
256
256
|
};
|
|
257
257
|
}
|
|
258
258
|
}
|
|
259
259
|
/**
|
|
260
260
|
* Block a stream for processing after failing to process and reaching max retries with blocking enabled.
|
|
261
|
+
* @param lease - The lease request.
|
|
261
262
|
* @param error Blocked error message.
|
|
262
263
|
*/
|
|
263
|
-
block(
|
|
264
|
-
if (this._leased_by === by) {
|
|
264
|
+
block(lease, error) {
|
|
265
|
+
if (this._leased_by === lease.by) {
|
|
265
266
|
this._blocked = true;
|
|
266
267
|
this._error = error;
|
|
267
268
|
return {
|
|
@@ -270,7 +271,8 @@ var InMemoryStream = class {
|
|
|
270
271
|
at: this._at,
|
|
271
272
|
by: this._leased_by,
|
|
272
273
|
retry: this._retry,
|
|
273
|
-
error: this._error
|
|
274
|
+
error: this._error,
|
|
275
|
+
lagging: lease.lagging
|
|
274
276
|
};
|
|
275
277
|
}
|
|
276
278
|
}
|
|
@@ -394,8 +396,18 @@ var InMemoryStore = class {
|
|
|
394
396
|
*/
|
|
395
397
|
async poll(lagging, leading) {
|
|
396
398
|
await sleep();
|
|
397
|
-
const a = [...this._streams.values()].filter((s) => s.is_avaliable).sort((a2, b2) => a2.at - b2.at).slice(0, lagging).map(({ stream, source, at }) => ({
|
|
398
|
-
|
|
399
|
+
const a = [...this._streams.values()].filter((s) => s.is_avaliable).sort((a2, b2) => a2.at - b2.at).slice(0, lagging).map(({ stream, source, at }) => ({
|
|
400
|
+
stream,
|
|
401
|
+
source,
|
|
402
|
+
at,
|
|
403
|
+
lagging: true
|
|
404
|
+
}));
|
|
405
|
+
const b = [...this._streams.values()].filter((s) => s.is_avaliable).sort((a2, b2) => b2.at - a2.at).slice(0, leading).map(({ stream, source, at }) => ({
|
|
406
|
+
stream,
|
|
407
|
+
source,
|
|
408
|
+
at,
|
|
409
|
+
lagging: false
|
|
410
|
+
}));
|
|
399
411
|
return [...a, ...b];
|
|
400
412
|
}
|
|
401
413
|
/**
|
|
@@ -410,7 +422,7 @@ var InMemoryStore = class {
|
|
|
410
422
|
if (!this._streams.has(l.stream)) {
|
|
411
423
|
this._streams.set(l.stream, new InMemoryStream(l.stream, l.source));
|
|
412
424
|
}
|
|
413
|
-
return this._streams.get(l.stream)?.lease(l
|
|
425
|
+
return this._streams.get(l.stream)?.lease(l, millis);
|
|
414
426
|
}).filter((l) => !!l);
|
|
415
427
|
}
|
|
416
428
|
/**
|
|
@@ -419,7 +431,7 @@ var InMemoryStore = class {
|
|
|
419
431
|
*/
|
|
420
432
|
async ack(leases) {
|
|
421
433
|
await sleep();
|
|
422
|
-
return leases.map((l) => this._streams.get(l.stream)?.ack(l
|
|
434
|
+
return leases.map((l) => this._streams.get(l.stream)?.ack(l)).filter((l) => !!l);
|
|
423
435
|
}
|
|
424
436
|
/**
|
|
425
437
|
* Block a stream for processing after failing to process and reaching max retries with blocking enabled.
|
|
@@ -428,7 +440,7 @@ var InMemoryStore = class {
|
|
|
428
440
|
*/
|
|
429
441
|
async block(leases) {
|
|
430
442
|
await sleep();
|
|
431
|
-
return leases.map((l) => this._streams.get(l.stream)?.block(l
|
|
443
|
+
return leases.map((l) => this._streams.get(l.stream)?.block(l, l.error)).filter((l) => !!l);
|
|
432
444
|
}
|
|
433
445
|
};
|
|
434
446
|
|
|
@@ -688,6 +700,7 @@ var Act = class {
|
|
|
688
700
|
}
|
|
689
701
|
_emitter = new EventEmitter();
|
|
690
702
|
_drain_locked = false;
|
|
703
|
+
_drain_lag2lead_ratio = 0.5;
|
|
691
704
|
_correlation_interval = void 0;
|
|
692
705
|
emit(event, args) {
|
|
693
706
|
return this._emitter.emit(event, args);
|
|
@@ -790,7 +803,7 @@ var Act = class {
|
|
|
790
803
|
* @returns The lease with results
|
|
791
804
|
*/
|
|
792
805
|
async handle(lease, payloads) {
|
|
793
|
-
if (payloads.length === 0) return { lease, at: lease.at };
|
|
806
|
+
if (payloads.length === 0) return { lease, handled: 0, at: lease.at };
|
|
794
807
|
const stream = lease.stream;
|
|
795
808
|
let at = payloads.at(0).event.id, handled = 0;
|
|
796
809
|
lease.retry > 0 && logger.warn(`Retrying ${stream}@${at} (${lease.retry}).`);
|
|
@@ -806,6 +819,7 @@ var Act = class {
|
|
|
806
819
|
block && logger.error(`Blocking ${stream} after ${lease.retry} retries.`);
|
|
807
820
|
return {
|
|
808
821
|
lease,
|
|
822
|
+
handled,
|
|
809
823
|
at,
|
|
810
824
|
// only report error when nothing was handled
|
|
811
825
|
error: handled === 0 ? error.message : void 0,
|
|
@@ -813,7 +827,7 @@ var Act = class {
|
|
|
813
827
|
};
|
|
814
828
|
}
|
|
815
829
|
}
|
|
816
|
-
return { lease, at };
|
|
830
|
+
return { lease, handled, at };
|
|
817
831
|
}
|
|
818
832
|
/**
|
|
819
833
|
* Drains and processes events from the store, triggering reactions and updating state.
|
|
@@ -833,27 +847,27 @@ var Act = class {
|
|
|
833
847
|
if (!this._drain_locked) {
|
|
834
848
|
try {
|
|
835
849
|
this._drain_locked = true;
|
|
836
|
-
const lagging = Math.ceil(streamLimit *
|
|
850
|
+
const lagging = Math.ceil(streamLimit * this._drain_lag2lead_ratio);
|
|
837
851
|
const leading = streamLimit - lagging;
|
|
838
852
|
const polled = await store().poll(lagging, leading);
|
|
839
853
|
const fetched = await Promise.all(
|
|
840
|
-
polled.map(async ({ stream, source, at }) => {
|
|
854
|
+
polled.map(async ({ stream, source, at, lagging: lagging2 }) => {
|
|
841
855
|
const events = await this.query_array({
|
|
842
856
|
stream: source,
|
|
843
857
|
after: at,
|
|
844
858
|
limit: eventLimit
|
|
845
859
|
});
|
|
846
|
-
return { stream, source, at, events };
|
|
860
|
+
return { stream, source, at, lagging: lagging2, events };
|
|
847
861
|
})
|
|
848
862
|
);
|
|
849
863
|
if (fetched.length) {
|
|
850
864
|
tracer.fetched(fetched);
|
|
851
865
|
const leases = /* @__PURE__ */ new Map();
|
|
852
|
-
const
|
|
866
|
+
const fetch_window_at = fetched.reduce(
|
|
853
867
|
(max, { at, events }) => Math.max(max, events.at(-1)?.id || at),
|
|
854
868
|
0
|
|
855
869
|
);
|
|
856
|
-
fetched.forEach(({ stream, events }) => {
|
|
870
|
+
fetched.forEach(({ stream, lagging: lagging2, events }) => {
|
|
857
871
|
const payloads = events.flatMap((event) => {
|
|
858
872
|
const register = this.registry.events[event.name] || [];
|
|
859
873
|
return [...register.reactions.values()].filter((reaction) => {
|
|
@@ -865,16 +879,17 @@ var Act = class {
|
|
|
865
879
|
lease: {
|
|
866
880
|
stream,
|
|
867
881
|
by: randomUUID2(),
|
|
868
|
-
at: events.at(-1)?.id ||
|
|
882
|
+
at: events.at(-1)?.id || fetch_window_at,
|
|
869
883
|
// ff when no matching events
|
|
870
|
-
retry: 0
|
|
884
|
+
retry: 0,
|
|
885
|
+
lagging: lagging2
|
|
871
886
|
},
|
|
872
887
|
// @ts-expect-error indexed by key
|
|
873
888
|
payloads
|
|
874
889
|
});
|
|
875
890
|
});
|
|
876
891
|
const leased = await store().lease(
|
|
877
|
-
[...leases.values()].map((
|
|
892
|
+
[...leases.values()].map(({ lease }) => lease),
|
|
878
893
|
leaseMillis
|
|
879
894
|
);
|
|
880
895
|
tracer.leased(leased);
|
|
@@ -883,6 +898,17 @@ var Act = class {
|
|
|
883
898
|
(lease) => this.handle(lease, leases.get(lease.stream).payloads)
|
|
884
899
|
)
|
|
885
900
|
);
|
|
901
|
+
const [lagging_handled, leading_handled] = handled.reduce(
|
|
902
|
+
([lagging_handled2, leading_handled2], { lease, handled: handled2 }) => [
|
|
903
|
+
lagging_handled2 + (lease.lagging ? handled2 : 0),
|
|
904
|
+
leading_handled2 + (lease.lagging ? 0 : handled2)
|
|
905
|
+
],
|
|
906
|
+
[0, 0]
|
|
907
|
+
);
|
|
908
|
+
const lagging_avg = lagging > 0 ? lagging_handled / lagging : 0;
|
|
909
|
+
const leading_avg = leading > 0 ? leading_handled / leading : 0;
|
|
910
|
+
const total = lagging_avg + leading_avg;
|
|
911
|
+
this._drain_lag2lead_ratio = total > 0 ? Math.max(0.2, Math.min(0.8, lagging_avg / total)) : 0.5;
|
|
886
912
|
const acked = await store().ack(
|
|
887
913
|
handled.filter(({ error }) => !error).map(({ at, lease }) => ({ ...lease, at }))
|
|
888
914
|
);
|
|
@@ -933,6 +959,7 @@ var Act = class {
|
|
|
933
959
|
by: randomUUID2(),
|
|
934
960
|
at: 0,
|
|
935
961
|
retry: 0,
|
|
962
|
+
lagging: true,
|
|
936
963
|
payloads
|
|
937
964
|
}));
|
|
938
965
|
const leased = await store().lease(leases, 0);
|