envio 3.1.0-rc.1 → 3.1.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/src/Throttler.res CHANGED
@@ -16,7 +16,7 @@ let make = (~intervalMillis: int, ~logger) => {
16
16
  logger,
17
17
  }
18
18
 
19
- let rec startInternal = async (throttler: t) => {
19
+ let rec startInternal = (throttler: t) => {
20
20
  switch throttler {
21
21
  | {scheduled: Some(fn), isRunning: false, isAwaitingInterval: false} =>
22
22
  let timeSinceLastRun = Date.now() -. throttler.lastRunTimeMillis
@@ -27,25 +27,32 @@ let rec startInternal = async (throttler: t) => {
27
27
  throttler.scheduled = None
28
28
  throttler.lastRunTimeMillis = Date.now()
29
29
 
30
- switch await fn() {
31
- | exception exn =>
32
- throttler.logger->Pino.errorExn(
33
- Pino.createPinoMessageWithError(
34
- "Scheduled action failed in throttler",
35
- exn->Utils.prettifyExn,
36
- ),
37
- )
38
- | _ => ()
39
- }
40
- throttler.isRunning = false
30
+ // Defer off the schedule call so work queued before it (e.g. a batch) runs first.
31
+ NodeJs.setImmediate(() => {
32
+ (
33
+ async () => {
34
+ switch await fn() {
35
+ | exception exn =>
36
+ throttler.logger->Pino.errorExn(
37
+ Pino.createPinoMessageWithError(
38
+ "Scheduled action failed in throttler",
39
+ exn->Utils.prettifyExn,
40
+ ),
41
+ )
42
+ | _ => ()
43
+ }
44
+ throttler.isRunning = false
41
45
 
42
- await throttler->startInternal
46
+ throttler->startInternal
47
+ }
48
+ )()->ignore
49
+ })
43
50
  } else {
44
51
  //Store isAwaitingInterval in state so that timers don't continuously get created
45
52
  throttler.isAwaitingInterval = true
46
53
  let _ = setTimeout(() => {
47
54
  throttler.isAwaitingInterval = false
48
- throttler->startInternal->ignore
55
+ throttler->startInternal
49
56
  }, Belt.Int.fromFloat(throttler.intervalMillis -. timeSinceLastRun))
50
57
  }
51
58
  | _ => ()
@@ -54,5 +61,5 @@ let rec startInternal = async (throttler: t) => {
54
61
 
55
62
  let schedule = (throttler: t, fn) => {
56
63
  throttler.scheduled = Some(fn)
57
- throttler->startInternal->ignore
64
+ throttler->startInternal
58
65
  }
@@ -15,7 +15,7 @@ function make(intervalMillis, logger) {
15
15
  };
16
16
  }
17
17
 
18
- async function startInternal(throttler) {
18
+ function startInternal(throttler) {
19
19
  let match = throttler.isRunning;
20
20
  if (match) {
21
21
  return;
@@ -33,20 +33,25 @@ async function startInternal(throttler) {
33
33
  throttler.isRunning = true;
34
34
  throttler.scheduled = undefined;
35
35
  throttler.lastRunTimeMillis = Date.now();
36
- try {
37
- await fn();
38
- } catch (raw_exn) {
39
- let exn = Primitive_exceptions.internalToException(raw_exn);
40
- throttler.logger.error(Pino.createPinoMessageWithError("Scheduled action failed in throttler", Utils.prettifyExn(exn)));
41
- }
42
- throttler.isRunning = false;
43
- return await startInternal(throttler);
36
+ setImmediate(() => {
37
+ (async () => {
38
+ try {
39
+ await fn();
40
+ } catch (raw_exn) {
41
+ let exn = Primitive_exceptions.internalToException(raw_exn);
42
+ throttler.logger.error(Pino.createPinoMessageWithError("Scheduled action failed in throttler", Utils.prettifyExn(exn)));
43
+ }
44
+ throttler.isRunning = false;
45
+ return startInternal(throttler);
46
+ })();
47
+ });
48
+ } else {
49
+ throttler.isAwaitingInterval = true;
50
+ setTimeout(() => {
51
+ throttler.isAwaitingInterval = false;
52
+ startInternal(throttler);
53
+ }, throttler.intervalMillis - timeSinceLastRun | 0);
44
54
  }
45
- throttler.isAwaitingInterval = true;
46
- setTimeout(() => {
47
- throttler.isAwaitingInterval = false;
48
- startInternal(throttler);
49
- }, throttler.intervalMillis - timeSinceLastRun | 0);
50
55
  }
51
56
 
52
57
  function schedule(throttler, fn) {
@@ -55,6 +55,7 @@ let initEffect = (params: contextParams) => {
55
55
  input,
56
56
  context: effectContext,
57
57
  cacheKey: input->S.reverseConvertOrThrow(effect.input)->Utils.Hash.makeOrThrow,
58
+ checkpointId: params.checkpointId,
58
59
  }
59
60
  LoadLayer.loadEffect(
60
61
  ~loadManager=params.loadManager,
@@ -39,10 +39,12 @@ function initEffect(params) {
39
39
  let callEffect = (effect, input) => {
40
40
  let effectContext = new EffectContext(params, effect.defaultShouldCache, callEffect);
41
41
  let effectArgs_cacheKey = Utils.Hash.makeOrThrow(S$RescriptSchema.reverseConvertOrThrow(input, effect.input));
42
+ let effectArgs_checkpointId = params.checkpointId;
42
43
  let effectArgs = {
43
44
  input: input,
44
45
  context: effectContext,
45
- cacheKey: effectArgs_cacheKey
46
+ cacheKey: effectArgs_cacheKey,
47
+ checkpointId: effectArgs_checkpointId
46
48
  };
47
49
  return LoadLayer.loadEffect(params.loadManager, params.persistence, effect, effectArgs, params.inMemoryStore, params.isPreload, params.item);
48
50
  };
@@ -8,6 +8,7 @@ type exitCode = | @as(0) Success | @as(1) Failure
8
8
  // which exposes named exports (exit, cwd) but not EventEmitter prototype methods (on, off, emit).
9
9
  @val external globalProcess: t = "process"
10
10
  @send external onUnhandledRejection: (t, @as("unhandledRejection") _, exn => unit) => unit = "on"
11
+ @val external setImmediate: (unit => unit) => unit = "setImmediate"
11
12
 
12
13
  module Util = {
13
14
  @unboxed