@toa.io/extensions.cadence 1.0.0-alpha.329 → 1.0.0-alpha.331

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.
@@ -31,6 +31,20 @@ entity:
31
31
  type: array
32
32
  items:
33
33
  type: string
34
+ schedule:
35
+ description: >
36
+ The cron expression of a schedule an operation handed over. Present, the row is the whole
37
+ of the schedule: settling it moves `due` to the next occurrence rather than disposing of it.
38
+ type: string
39
+ zone:
40
+ description: The time zone `schedule` is read in
41
+ type: string
42
+ overdue:
43
+ description: >
44
+ Milliseconds an occurrence of a schedule may be late and still be made. Absent, it is owed
45
+ until the next occurrence comes due.
46
+ type: integer
47
+ minimum: 0
34
48
  required:
35
49
  - lane
36
50
  - due
@@ -76,3 +90,34 @@ operations:
76
90
  query: true
77
91
  # a row may be cancelled while a page of them is being settled
78
92
  concurrency: retry
93
+ input:
94
+ type: object
95
+ nullable: true
96
+ properties:
97
+ made:
98
+ description: >
99
+ The occurrence each recurring row was disposed of at, by id. A row that has moved
100
+ past it since is left where it is.
101
+ type: object
102
+ additionalProperties:
103
+ type: integer
104
+ ended:
105
+ description: Recurring rows that are over, which are disposed of rather than moved on
106
+ type: array
107
+ items:
108
+ type: string
109
+
110
+ # a schedule handed over again after it was cancelled or had ended, which holds its id
111
+ resume:
112
+ query: true
113
+ concurrency: retry
114
+ input:
115
+ type: object
116
+ properties:
117
+ due:
118
+ type: integer
119
+ lane:
120
+ type: integer
121
+ required:
122
+ - due
123
+ - lane
@@ -0,0 +1,9 @@
1
+ /**
2
+ * A schedule handed over again after it was cancelled or had ended. What it is is its id, so the
3
+ * row is the same one: committed without touching `DELETED`, a tombstone is revived, and it waits
4
+ * for the first occurrence from now.
5
+ */
6
+ export function transition(input, entry) {
7
+ entry.due = input.due
8
+ entry.lane = input.lane
9
+ }
@@ -1,3 +1,5 @@
1
+ import { following } from '@toa.io/extensions.cadence'
2
+
1
3
  /**
2
4
  * The rows whose calls have been disposed of — made, or found past the bound their caller gave
3
5
  * them. They are tombstoned rather than removed: the record of what was asked for outlives the
@@ -5,9 +7,29 @@
5
7
  *
6
8
  * `DELETED` is also what the retention index reaps by, so that the record outlives the call
7
9
  * without outliving the deployment.
10
+ *
11
+ * A row that carries a schedule is the whole of it, and is moved on to its next occurrence
12
+ * instead — unless it is over, or nothing comes before it expires.
8
13
  */
9
- export function transition(_, entries) {
14
+ export function transition(input, entries) {
10
15
  const now = Date.now()
16
+ const made = input?.made ?? {}
17
+ const ended = new Set(input?.ended ?? [])
18
+
19
+ for (const entry of entries) {
20
+ if (entry.schedule === undefined || ended.has(entry.id)) {
21
+ entry.DELETED = now
22
+
23
+ continue
24
+ }
25
+
26
+ // a settle that arrives after the row has moved on — a second one, or one from a replica
27
+ // whose lane changed hands — leaves it where it is: the occurrence it is at is not made yet
28
+ if (made[entry.id] !== entry.due) continue
29
+
30
+ const due = following(entry, now)
11
31
 
12
- for (const entry of entries) entry.DELETED = now
32
+ if (due === null) entry.DELETED = now
33
+ else entry.due = due
34
+ }
13
35
  }
@@ -17,6 +17,12 @@ export interface Entity {
17
17
  request?: Record<string, unknown>
18
18
  /** The chain of hops that asked for the call, which the call is then made by. A delay is a hop like any other, so a circle routed through one is still a circle. Absent where the caller unchained the call, and on a row written before this existed. */
19
19
  trail?: string[]
20
+ /** The cron expression of a schedule an operation handed over. Present, the row is the whole of the schedule: settling it moves `due` to the next occurrence rather than disposing of it. */
21
+ schedule?: string
22
+ /** The time zone `schedule` is read in */
23
+ zone?: string
24
+ /** Milliseconds an occurrence of a schedule may be late and still be made. Absent, it is owed until the next occurrence comes due. */
25
+ overdue?: number
20
26
  id: string
21
27
  VERSION: number
22
28
  CREATED: number
@@ -39,9 +45,22 @@ export type DelayInput = {
39
45
 
40
46
  export type DelayOutput = string
41
47
 
48
+ export type SettleInput = {
49
+ /** The occurrence each recurring row was disposed of at, by id. A row that has moved past it since is left where it is. */
50
+ made?: Record<string, number>
51
+ /** Recurring rows that are over, which are disposed of rather than moved on */
52
+ ended?: string[]
53
+ } | null
54
+
55
+ export type ResumeInput = {
56
+ due: number
57
+ lane: number
58
+ }
59
+
42
60
  export interface Component {
43
61
  delay: (request: { input: DelayInput, task?: boolean }) => Promise<DelayOutput>
44
- settle: (request: { input?: null, query: Query<Entity>, task?: boolean }) => Promise<unknown>
62
+ settle: (request: { input: SettleInput, query: Query<Entity>, task?: boolean }) => Promise<unknown>
63
+ resume: (request: { input: ResumeInput, query: Query<Entity>, task?: boolean }) => Promise<unknown>
45
64
  assign: (request: { input?: null, query?: Query<Entity>, task?: boolean }) => Promise<Entity>
46
65
  ensure: (request: { input?: null, query?: Query<Entity>, entity?: Partial<Entity>, task?: boolean }) => Promise<Entity>
47
66
  enumerate: (request: { input?: null, query?: Query<Entity>, task?: boolean }) => Promise<Entity[]>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toa.io/extensions.cadence",
3
- "version": "1.0.0-alpha.329",
3
+ "version": "1.0.0-alpha.331",
4
4
  "type": "module",
5
5
  "description": "Toa Schedule",
6
6
  "author": "temich <tema.gurtovoy@gmail.com>",
@@ -26,14 +26,14 @@
26
26
  "!**/.env*"
27
27
  ],
28
28
  "dependencies": {
29
- "@toa.io/core": "1.0.0-alpha.329",
30
- "@toa.io/definitions": "1.0.0-alpha.329",
31
- "@toa.io/generic": "1.0.0-alpha.329",
32
- "@toa.io/schemas": "1.0.0-alpha.329",
33
- "openspan": "1.0.0-alpha.327"
29
+ "@toa.io/core": "1.0.0-alpha.330",
30
+ "@toa.io/definitions": "1.0.0-alpha.331",
31
+ "@toa.io/generic": "1.0.0-alpha.330",
32
+ "@toa.io/schemas": "1.0.0-alpha.330",
33
+ "openspan": "1.0.0-alpha.330"
34
34
  },
35
35
  "scripts": {
36
36
  "transpile": "tsc"
37
37
  },
38
- "gitHead": "a2751218f403615dda260a6f7469d182eb8864d0"
38
+ "gitHead": "e7020d160910ca4f0c2ff9040b3cbb4fca8ea41f"
39
39
  }
package/readme.md CHANGED
@@ -4,7 +4,7 @@ Calls a component makes to itself, and calls it puts off.
4
4
 
5
5
  A **pulse** calls an operation of its own component on a cadence its manifest states. A
6
6
  **schedule** calls one at the moments of a calendar. A **delay** hands one call over to be made
7
- later.
7
+ later, and an operation may [hand a schedule over](#handed-over) the same way.
8
8
 
9
9
  A delay, a schedule, and a pulse that is the component's rather than each replica's, rest on
10
10
  [`atomicity`](/connectors/atomicity), which is what keeps two replicas from making one call and
@@ -299,8 +299,9 @@ begins a chain of its own on every call, delayed or not, and needs no option her
299
299
 
300
300
  A [pulse](#pulse) is the other way to write recurring work, and where it fits it is the simpler
301
301
  one: one timer for the component rather than a row per item, and no chain to break, because it
302
- is called from the clock. Reach for a delay instead when each item has its own schedule — this
303
- invoice a day from now, that one in a week.
302
+ is called from the clock. Reach for a delay instead when each item has its own moment — this
303
+ invoice a day from now, that one in a week — and for a [schedule handed over](#handed-over) when
304
+ each item has its own calendar.
304
305
 
305
306
  Nothing is declared for it beyond naming the extension. A component that only delays calls says
306
307
  so with an empty declaration:
@@ -390,6 +391,74 @@ A horizon of years costs nothing, and a call put off that long is worth no more
390
391
  that will be there to take it: the target may be gone by the time it comes due, and its input
391
392
  may no longer be one it accepts. Either way the attempt is spent.
392
393
 
394
+ ## Handed over
395
+
396
+ ```javascript
397
+ const id = await context.schedule(
398
+ 'mail.digest.send',
399
+ { input: { account } },
400
+ { schedule: '0 9 * * 1', zone: 'Europe/Berlin' }
401
+ )
402
+
403
+ await context.schedule.cancel(id)
404
+ ```
405
+
406
+ A schedule of an item's own: the target is called at every occurrence until the schedule expires
407
+ or is cancelled. The third argument is a cron expression, as a manifest's [schedule](#schedule) states
408
+ one, or an object:
409
+
410
+ | | |
411
+ | ---------- | -------------------------------------------------------------------------------- |
412
+ | `schedule` | the cron expression, of five fields or of six where the first is seconds |
413
+ | `zone` | the [time zone](https://www.iana.org/time-zones) it is read in, `UTC` by default |
414
+ | `overdue` | milliseconds a call may be late and still be made; until the next one by default |
415
+ | `expires` | milliseconds since the epoch after which nothing is called; no end by default |
416
+
417
+ The endpoint is named as a [delay](#delay) names it. The id answered is what cancels the
418
+ schedule, and `cancel` raises where the id was never issued. Keep it beside the item the schedule
419
+ is for: nothing lists schedules, and nothing changes one — a schedule is changed by cancelling it
420
+ and handing the new one over.
421
+
422
+ **The same schedule handed over twice is one.** The same endpoint, request, expression, zone and
423
+ `expires` answer the same id and store nothing more, so an operation that runs twice for one call does not
424
+ make every occurrence twice.
425
+
426
+ The target is called with the input that was handed over and the moment of the occurrence beside
427
+ it, in milliseconds since the epoch, so its contract states `at` as well:
428
+
429
+ ```javascript
430
+ async function send({ account, at }, context) {}
431
+ ```
432
+
433
+ An expression or a zone that does not parse, an `expires` already past, a request that names an
434
+ `instance`, and an input that is not an object or already states `at` are refused where `context.schedule` is called, and nothing
435
+ is stored. Storing a schedule is a write, so it is refused from a chain that
436
+ [may only read](/documentation/readonly.md), as a delay is.
437
+
438
+ ### What to expect
439
+
440
+ What a manifest's [schedule](#what-to-expect-1) does, it does: a call is late rather than lost, an
441
+ occurrence is not made once the next one is due, `at` is the moment of the occurrence and not of
442
+ the call, and nothing keeps a call from running while the one before it is.
443
+
444
+ **A call may be made more than once**, and a second call of one occurrence is the same call, so an
445
+ operation that declares [`once`](/documentation/inbox.md) changes state once per occurrence.
446
+
447
+ **A call that was not made ends nothing.** An occurrence that expired, was refused on the way out,
448
+ or fell while nothing was running is not made up, and the next one is made.
449
+
450
+ **A target that will never take the call ends the schedule** — an endpoint it no longer has, or a
451
+ request its contract no longer fits. That is logged, and nothing is called again.
452
+
453
+ **Each call begins a chain of its own**, whatever chain handed the schedule over.
454
+
455
+ **Occurrences closer together than [`discreteness`](#discreteness) are made at most once a
456
+ pass**, and the ones in between are not made. A cancellation is reliable as a delay's is: while
457
+ the next occurrence is further out than `discreteness`.
458
+
459
+ A schedule is made by the region that handed it over, and is [taken over](#regions) with that
460
+ region's delayed calls.
461
+
393
462
  ## Configuration
394
463
 
395
464
  ```yaml
@@ -7,8 +7,13 @@ export declare class Dispatcher extends Connector {
7
7
  private readonly atom;
8
8
  /** rows in this replica's hands — a timer set for them, or a call of theirs on its way */
9
9
  private readonly armed;
10
- /** ids called and not yet removed, held until a scan settles them */
10
+ /**
11
+ * Ids called and not yet settled, held until a scan settles them, with the occurrence each was
12
+ * at: a recurring row is moved on from that one, and from no other.
13
+ */
11
14
  private called;
15
+ /** recurring rows that are over — expired, or refused for good — held as `called` is */
16
+ private ended;
12
17
  /** what it has called through, so that each is torn down with it */
13
18
  private readonly targets;
14
19
  /** milliseconds between passes, and how far ahead each one reaches */
@@ -1,6 +1,7 @@
1
1
  import { console } from 'openspan';
2
- import { Connector, Locator, exceptions } from '@toa.io/core';
2
+ import { Connector, Locator, entities, exceptions } from '@toa.io/core';
3
3
  import * as measure from './measurements.js';
4
+ import { bound } from './row.js';
4
5
  import { BATCH, DISCRETENESS, LANES, number, regions } from '@toa.io/definitions/extensions.cadence';
5
6
  /**
6
7
  * Makes the calls that were put off.
@@ -25,8 +26,13 @@ export class Dispatcher extends Connector {
25
26
  atom;
26
27
  /** rows in this replica's hands — a timer set for them, or a call of theirs on its way */
27
28
  armed = new Map();
28
- /** ids called and not yet removed, held until a scan settles them */
29
- called = new Set();
29
+ /**
30
+ * Ids called and not yet settled, held until a scan settles them, with the occurrence each was
31
+ * at: a recurring row is moved on from that one, and from no other.
32
+ */
33
+ called = new Map();
34
+ /** recurring rows that are over — expired, or refused for good — held as `called` is */
35
+ ended = new Set();
30
36
  /** what it has called through, so that each is torn down with it */
31
37
  targets = new Set();
32
38
  /** milliseconds between passes, and how far ahead each one reaches */
@@ -230,9 +236,25 @@ export class Dispatcher extends Connector {
230
236
  * until its call has been made.
231
237
  */
232
238
  arm(row) {
233
- if (this.armed.has(row.id) || this.called.has(row.id))
239
+ if (this.armed.has(row.id) || this.called.has(row.id) || this.ended.has(row.id))
234
240
  return;
235
241
  const now = Date.now();
242
+ /*
243
+ * A recurring row is one schedule, and `expires` is its end: past it the row is disposed of
244
+ * rather than moved on. Short of it, the occurrence it waits for has a bound of its own, and
245
+ * one past that is not made and is moved on from, as a delayed call past its bound is settled.
246
+ */
247
+ if (row.schedule !== undefined) {
248
+ if (row.expires <= now) {
249
+ this.ended.add(row.id);
250
+ return;
251
+ }
252
+ if (bound(row) <= now) {
253
+ measure.lapsed(component(row.endpoint));
254
+ this.called.set(row.id, row.due);
255
+ return;
256
+ }
257
+ }
236
258
  /*
237
259
  * Past the bound its caller gave it, so the call is not made — and the row is settled all
238
260
  * the same, silently, because an expired call is not an event anything sees. Left unread
@@ -241,7 +263,7 @@ export class Dispatcher extends Connector {
241
263
  */
242
264
  if (row.expires <= now) {
243
265
  measure.lapsed(component(row.endpoint));
244
- this.called.add(row.id);
266
+ this.called.set(row.id, row.due);
245
267
  return;
246
268
  }
247
269
  const timer = setTimeout(() => {
@@ -277,6 +299,18 @@ export class Dispatcher extends Connector {
277
299
  * is why this is set after the spread as well.
278
300
  */
279
301
  request.id = row.id;
302
+ /*
303
+ * A recurring row is many calls, one an occurrence: each is told which by `at`, and is a call
304
+ * of its own identity, so a second call of one occurrence is that call again and the next
305
+ * occurrence is another.
306
+ */
307
+ if (row.schedule !== undefined) {
308
+ request.input = {
309
+ ...row.request?.input,
310
+ at: row.due
311
+ };
312
+ request.id = entities.derive(row.id, row.due);
313
+ }
280
314
  /*
281
315
  * The call travels as a task, so what raises here is this side of it: a stored request the
282
316
  * target's contract no longer fits, an endpoint it no longer has, a broker that refused the
@@ -293,15 +327,22 @@ export class Dispatcher extends Connector {
293
327
  .invoke(endpoint, request)
294
328
  .then(() => {
295
329
  measure.made(component(row.endpoint));
296
- this.called.add(row.id);
330
+ this.called.set(row.id, row.due);
297
331
  })
298
332
  .catch((error) => {
333
+ // a schedule whose call the target will never take is over, rather than refused again
334
+ // at every occurrence for as long as the application runs
299
335
  if (exceptions.permanent(error))
300
- this.called.add(row.id);
336
+ if (row.schedule === undefined)
337
+ this.called.set(row.id, row.due);
338
+ else
339
+ this.ended.add(row.id);
301
340
  console.error('Delayed call failed', {
302
341
  endpoint: row.endpoint,
303
342
  id: row.id,
304
343
  permanent: exceptions.permanent(error),
344
+ // a schedule refused for good is over, and this is the only place that says so
345
+ ...(row.schedule !== undefined && { ended: exceptions.permanent(error) }),
305
346
  error
306
347
  });
307
348
  })
@@ -325,13 +366,17 @@ export class Dispatcher extends Connector {
325
366
  }
326
367
  /** One write for many rows, which is why the ids are held rather than settled one by one. */
327
368
  async settle() {
328
- if (this.called.size === 0)
369
+ if (this.called.size === 0 && this.ended.size === 0)
329
370
  return;
330
- const ids = [...this.called];
331
- await this.metronome.invoke('settle', { query: { ids }, input: null });
371
+ const made = Object.fromEntries(this.called);
372
+ const ended = [...this.ended];
373
+ const ids = [...Object.keys(made), ...ended];
374
+ await this.metronome.invoke('settle', { query: { ids }, input: { made, ended } });
332
375
  // held until the write comes back, so that one which does not leaves them to a later scan
333
- for (const id of ids)
376
+ for (const id of Object.keys(made))
334
377
  this.called.delete(id);
378
+ for (const id of ended)
379
+ this.ended.delete(id);
335
380
  }
336
381
  }
337
382
  /** intervals a scan may run for before it is a stuck pass rather than a slow one */
@@ -1 +1 @@
1
- {"version":3,"file":"Dispatcher.js","sourceRoot":"","sources":["../source/Dispatcher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Dispatcher.js","sourceRoot":"","sources":["../source/Dispatcher.ts"],"names":[],"mappings":"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"}
@@ -13,7 +13,7 @@ export declare class Factory implements extensions.Factory {
13
13
  * reaches for one.
14
14
  */
15
15
  tenant(locator: Locator, declaration: object): Connector;
16
- /** `context.delay` — for every component but the one that keeps the calls. */
16
+ /** `context.delay` and `context.schedule` — for every component but the one that keeps the calls. */
17
17
  aspect(locator: Locator): extensions.Aspect | extensions.Aspect[];
18
18
  service(): Connector;
19
19
  private metronome;
@@ -6,6 +6,7 @@ import { Dispatcher } from './Dispatcher.js';
6
6
  import { Local } from './Local.js';
7
7
  import { Pulse } from './Pulse.js';
8
8
  import { Schedule } from './Schedule.js';
9
+ import { Scheduler } from './Scheduler.js';
9
10
  export class Factory {
10
11
  host;
11
12
  /** one per component, however much of this extension calls through it */
@@ -52,11 +53,11 @@ export class Factory {
52
53
  tenant.depends(new Pulse({ locator, endpoint, cycle: entry.cycle, intervals: entry.intervals }, local, entry.scope === 'group' ? atom : undefined));
53
54
  return tenant;
54
55
  }
55
- /** `context.delay` — for every component but the one that keeps the calls. */
56
+ /** `context.delay` and `context.schedule` — for every component but the one that keeps the calls. */
56
57
  aspect(locator) {
57
58
  if (mine(locator))
58
59
  return [];
59
- return new Aspect(this.metronome());
60
+ return [new Aspect(this.metronome()), new Scheduler(this.metronome())];
60
61
  }
61
62
  // nothing connects to this, so a halt takes the whole of it
62
63
  service() {
@@ -1 +1 @@
1
- {"version":3,"file":"Factory.js","sourceRoot":"","sources":["../source/Factory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Factory.js","sourceRoot":"","sources":["../source/Factory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { Connector } from '@toa.io/core';
2
+ import type { Local } from './Local.ts';
3
+ /**
4
+ * `context.schedule(endpoint, request, schedule)` — a call made at every occurrence of a calendar,
5
+ * handed to the component that keeps delayed calls as one row it moves on as each occurrence is
6
+ * disposed of.
7
+ *
8
+ * Like a delay it is not transactional with the caller's state. Unlike one, handing it over twice
9
+ * is harmless: the id is what is scheduled, so the second is the first.
10
+ */
11
+ export declare class Scheduler extends Connector {
12
+ readonly name = "schedule";
13
+ private readonly metronome;
14
+ constructor(metronome: Local);
15
+ invoke(method: string, ...args: any[]): Promise<unknown>;
16
+ /** Answers the id of the schedule, which is what cancels it. */
17
+ private schedule;
18
+ /** Revives the tombstone of a schedule handed over again, waiting for its first occurrence. */
19
+ private resume;
20
+ /** Tombstones the row, as cancelling a delay does. */
21
+ private cancel;
22
+ }
@@ -0,0 +1,140 @@
1
+ import { Connector, entities, exceptions } from '@toa.io/core';
2
+ import { occurrences } from '@toa.io/definitions/extensions.cadence';
3
+ import { recurring } from './row.js';
4
+ /**
5
+ * `context.schedule(endpoint, request, schedule)` — a call made at every occurrence of a calendar,
6
+ * handed to the component that keeps delayed calls as one row it moves on as each occurrence is
7
+ * disposed of.
8
+ *
9
+ * Like a delay it is not transactional with the caller's state. Unlike one, handing it over twice
10
+ * is harmless: the id is what is scheduled, so the second is the first.
11
+ */
12
+ export class Scheduler extends Connector {
13
+ name = 'schedule';
14
+ metronome;
15
+ constructor(metronome) {
16
+ super();
17
+ this.metronome = metronome;
18
+ this.depends(metronome);
19
+ }
20
+ // named rather than forwarded, as the delay aspect's are
21
+ async invoke(method, ...args) {
22
+ switch (method) {
23
+ case 'schedule':
24
+ return await this.schedule(args[0], args[1], args[2]);
25
+ case 'cancel':
26
+ return await this.cancel(args[0]);
27
+ default:
28
+ throw new Error(`Schedule aspect has no '${method}' method`);
29
+ }
30
+ }
31
+ /** Answers the id of the schedule, which is what cancels it. */
32
+ async schedule(endpoint, request, stated) {
33
+ const { schedule, zone, overdue, expires } = recurrence(stated);
34
+ // a call that goes out as a task names no process, as a delayed call names none
35
+ if (request !== null && request !== undefined && 'instance' in request)
36
+ throw new exceptions.RequestContractException('A scheduled call names no `instance`');
37
+ const input = request?.input;
38
+ // the occurrence is added to the input, so there has to be an object to add it to, and one
39
+ // that does not already say what it would be overwriting
40
+ if (input !== undefined && input !== null) {
41
+ if (typeof input !== 'object' || Array.isArray(input))
42
+ throw new exceptions.RequestContractException('The input of a scheduled call is an object, to which its occurrence is added as `at`');
43
+ if ('at' in input)
44
+ throw new exceptions.RequestContractException('The input of a scheduled call states no `at`: that is the occurrence it is made for');
45
+ }
46
+ let next;
47
+ try {
48
+ next = occurrences(schedule, zone);
49
+ }
50
+ catch (error) {
51
+ throw new exceptions.RequestContractException(error.message);
52
+ }
53
+ const now = Date.now();
54
+ const due = next(now);
55
+ if (expires !== undefined && (due === null || due > expires))
56
+ throw new exceptions.RequestContractException(`The schedule '${schedule}' expires before its first occurrence`);
57
+ // a component that declares no namespace is named by its name, and called by its id
58
+ if (endpoint.split('.').length === 2)
59
+ endpoint = `default.${endpoint}`;
60
+ /*
61
+ * What is scheduled is what the schedule is, so a second hand-over of it — a redelivery, a
62
+ * retried transition — is the same row rather than a second call at every occurrence for good.
63
+ */
64
+ const id = entities.derive('cadence', 'schedule', endpoint, canonical(request ?? null), schedule, zone, expires ?? '');
65
+ const entity = {
66
+ id,
67
+ ...recurring({
68
+ endpoint,
69
+ due: due,
70
+ request: request ?? undefined,
71
+ schedule,
72
+ zone,
73
+ overdue,
74
+ expires
75
+ })
76
+ };
77
+ /*
78
+ * A schedule that was cancelled or had ended holds its id as a tombstone, and a fresh one
79
+ * cannot be written beside it: that one is revived instead. Read first rather than told by
80
+ * the write refusing, because a refusal is an operation that failed, and is logged as one.
81
+ *
82
+ * Raises from a chain that may only read, as `delay` does: storing it is a write.
83
+ */
84
+ const found = (await this.metronome.invoke('observe', {
85
+ query: { id, deleted: true }
86
+ }));
87
+ if (found !== null && found.DELETED !== null && found.DELETED !== undefined)
88
+ await this.resume(id, entity);
89
+ else
90
+ try {
91
+ await this.metronome.invoke('ensure', { query: { id }, entity });
92
+ }
93
+ catch (error) {
94
+ // cancelled between the read and the write
95
+ if (error?.code === DUPLICATE)
96
+ await this.resume(id, entity);
97
+ else
98
+ throw error;
99
+ }
100
+ return id;
101
+ }
102
+ /** Revives the tombstone of a schedule handed over again, waiting for its first occurrence. */
103
+ async resume(id, entity) {
104
+ await this.metronome.invoke('resume', {
105
+ query: { id, deleted: true },
106
+ input: { due: entity.due, lane: entity.lane }
107
+ });
108
+ }
109
+ /** Tombstones the row, as cancelling a delay does. */
110
+ async cancel(id) {
111
+ return await this.metronome.invoke('terminate', { query: { id }, input: null });
112
+ }
113
+ }
114
+ function recurrence(stated) {
115
+ const declared = typeof stated === 'string' ? { schedule: stated } : stated;
116
+ if (declared === null ||
117
+ typeof declared !== 'object' ||
118
+ typeof declared.schedule !== 'string')
119
+ throw new exceptions.RequestContractException('A schedule is a cron expression, or an object stating one as `schedule`');
120
+ const { schedule, zone = 'UTC', overdue, expires } = declared;
121
+ if (typeof zone !== 'string')
122
+ throw new exceptions.RequestContractException('A schedule names its `zone` by a string');
123
+ if (overdue !== undefined && !(Number.isInteger(overdue) && overdue >= 0))
124
+ throw new exceptions.RequestContractException('The `overdue` of a schedule is a whole number of milliseconds');
125
+ if (expires !== undefined && !Number.isInteger(expires))
126
+ throw new exceptions.RequestContractException('The `expires` of a schedule is milliseconds since the epoch');
127
+ return { schedule, zone, overdue, expires };
128
+ }
129
+ /** what storing a row under an id a tombstone already holds raises */
130
+ const DUPLICATE = exceptions.codes.Duplicate;
131
+ /**
132
+ * JSON with the keys of every object in order, so that two requests that say the same thing are
133
+ * one schedule however their keys were written.
134
+ */
135
+ function canonical(value) {
136
+ return JSON.stringify(value, (_, value) => value !== null && typeof value === 'object' && !Array.isArray(value)
137
+ ? Object.fromEntries(Object.entries(value).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)))
138
+ : value);
139
+ }
140
+ //# sourceMappingURL=Scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Scheduler.js","sourceRoot":"","sources":["../source/Scheduler.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  export { Factory } from './Factory.ts';
2
2
  export { components } from './Composition.ts';
3
3
  export { LANES } from '@toa.io/definitions/extensions.cadence';
4
- export { row } from './row.ts';
5
- export type { Declaration, Delay, Entry, Pulse, Schedule } from '@toa.io/definitions/extensions.cadence';
4
+ export { row, following } from './row.ts';
5
+ export type { Declaration, Delay, Entry, Pulse, Recurrence, Schedule, Scheduler } from '@toa.io/definitions/extensions.cadence';
@@ -2,5 +2,5 @@ export { Factory } from './Factory.js';
2
2
  export { components } from './Composition.js';
3
3
  // what the metronome component is written against
4
4
  export { LANES } from '@toa.io/definitions/extensions.cadence';
5
- export { row } from './row.js';
5
+ export { row, following } from './row.js';
6
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../source/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,kDAAkD;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,wCAAwC,CAAA;AAC9D,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../source/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,kDAAkD;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,wCAAwC,CAAA;AAC9D,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA"}
@@ -9,6 +9,29 @@
9
9
  * dispatchers want.
10
10
  */
11
11
  export declare function row(call: Call): Stored;
12
+ /**
13
+ * What is stored of a schedule an operation handed over: one row, whose `due` is the occurrence it
14
+ * waits for and which `settle` moves on to the next one, rather than a row per occurrence.
15
+ *
16
+ * `expires` keeps the meaning it has on every row — nothing of the row is made after it — and is
17
+ * the end of the schedule, or the end of representable time where it has none. How late one
18
+ * occurrence may be is what `overdue` says, and is derived where it is read: see `bound`.
19
+ */
20
+ export declare function recurring(call: Recurring): Stored;
21
+ /**
22
+ * The moment past which the occurrence a recurring row waits for is no longer made: `overdue`
23
+ * after it where one was stated, and the next occurrence where none was, so that at most one is
24
+ * ever owed.
25
+ */
26
+ export declare function bound(stored: Stored): number;
27
+ /**
28
+ * The occurrence a recurring row moves on to once the one it waited for is disposed of: the first
29
+ * after now and never one already past, so a metronome that was away owes one occurrence and not
30
+ * every one it missed. Never the one it was at, either — a call made a moment early, or a clock
31
+ * behind the one that wrote `due`, would otherwise make it again. `null` where nothing comes
32
+ * before the row expires.
33
+ */
34
+ export declare function following(stored: Stored, now: number): number | null;
12
35
  export interface Call {
13
36
  /** what to call, as `namespace.component.operation` */
14
37
  endpoint: string;
@@ -19,6 +42,21 @@ export interface Call {
19
42
  request?: object;
20
43
  trail?: string[];
21
44
  }
45
+ export interface Recurring {
46
+ /** what to call, as `namespace.component.operation` */
47
+ endpoint: string;
48
+ /** the first occurrence, in milliseconds since the epoch */
49
+ due: number;
50
+ request?: object;
51
+ /** the cron expression */
52
+ schedule: string;
53
+ /** the time zone it is read in */
54
+ zone: string;
55
+ /** milliseconds an occurrence may be late and still be made; until the next one where absent */
56
+ overdue?: number;
57
+ /** milliseconds since the epoch after which nothing is made; never where absent */
58
+ expires?: number;
59
+ }
22
60
  export interface Stored {
23
61
  lane: number;
24
62
  due: number;
@@ -26,4 +64,9 @@ export interface Stored {
26
64
  endpoint: string;
27
65
  request?: object;
28
66
  trail?: string[];
67
+ /** what a recurring row recurs by, absent on a row that is made once */
68
+ schedule?: string;
69
+ zone?: string;
70
+ /** milliseconds an occurrence of a recurring row may be late */
71
+ overdue?: number;
29
72
  }
package/transpiled/row.js CHANGED
@@ -1,4 +1,4 @@
1
- import { LANES } from '@toa.io/definitions/extensions.cadence';
1
+ import { LANES, occurrences } from '@toa.io/definitions/extensions.cadence';
2
2
  /**
3
3
  * What is stored of a call to make later, as whoever hands one over states it: `context.delay`,
4
4
  * and a schedule storing its next occurrence. Written once, so that the two store one kind of
@@ -29,4 +29,52 @@ export function row(call) {
29
29
  stored.trail = trail;
30
30
  return stored;
31
31
  }
32
+ /**
33
+ * What is stored of a schedule an operation handed over: one row, whose `due` is the occurrence it
34
+ * waits for and which `settle` moves on to the next one, rather than a row per occurrence.
35
+ *
36
+ * `expires` keeps the meaning it has on every row — nothing of the row is made after it — and is
37
+ * the end of the schedule, or the end of representable time where it has none. How late one
38
+ * occurrence may be is what `overdue` says, and is derived where it is read: see `bound`.
39
+ */
40
+ export function recurring(call) {
41
+ const { endpoint, due, request, schedule, zone, overdue, expires } = call;
42
+ const stored = {
43
+ lane: Math.floor(Math.random() * LANES),
44
+ due,
45
+ endpoint,
46
+ expires: expires ?? Number.MAX_SAFE_INTEGER,
47
+ schedule,
48
+ zone
49
+ };
50
+ if (overdue !== undefined)
51
+ stored.overdue = overdue;
52
+ if (request !== undefined)
53
+ stored.request = request;
54
+ return stored;
55
+ }
56
+ /**
57
+ * The moment past which the occurrence a recurring row waits for is no longer made: `overdue`
58
+ * after it where one was stated, and the next occurrence where none was, so that at most one is
59
+ * ever owed.
60
+ */
61
+ export function bound(stored) {
62
+ if (stored.overdue !== undefined)
63
+ return stored.due + stored.overdue;
64
+ return next(stored, stored.due) ?? Number.MAX_SAFE_INTEGER;
65
+ }
66
+ /**
67
+ * The occurrence a recurring row moves on to once the one it waited for is disposed of: the first
68
+ * after now and never one already past, so a metronome that was away owes one occurrence and not
69
+ * every one it missed. Never the one it was at, either — a call made a moment early, or a clock
70
+ * behind the one that wrote `due`, would otherwise make it again. `null` where nothing comes
71
+ * before the row expires.
72
+ */
73
+ export function following(stored, now) {
74
+ const at = next(stored, Math.max(now, stored.due));
75
+ return at === null || at > stored.expires ? null : at;
76
+ }
77
+ function next(stored, after) {
78
+ return occurrences(stored.schedule, stored.zone)(after);
79
+ }
32
80
  //# sourceMappingURL=row.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"row.js","sourceRoot":"","sources":["../source/row.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,wCAAwC,CAAA;AAE9D;;;;;;;;;GASG;AACH,MAAM,UAAU,GAAG,CAAC,IAAU;IAC5B,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAA;IAEvD,MAAM,MAAM,GAAW;QACrB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC;QACvC,GAAG;QACH,QAAQ;QAER,6FAA6F;QAC7F,qFAAqF;QACrF,mCAAmC;QACnC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,GAAG,OAAO;KACpE,CAAA;IAED,yFAAyF;IACzF,4CAA4C;IAC5C,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAA;IAEnD,iFAAiF;IACjF,IAAI,KAAK,KAAK,SAAS;QAAE,MAAM,CAAC,KAAK,GAAG,KAAK,CAAA;IAE7C,OAAO,MAAM,CAAA;AACf,CAAC"}
1
+ {"version":3,"file":"row.js","sourceRoot":"","sources":["../source/row.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAA;AAE3E;;;;;;;;;GASG;AACH,MAAM,UAAU,GAAG,CAAC,IAAU;IAC5B,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAA;IAEvD,MAAM,MAAM,GAAW;QACrB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC;QACvC,GAAG;QACH,QAAQ;QAER,6FAA6F;QAC7F,qFAAqF;QACrF,mCAAmC;QACnC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,GAAG,OAAO;KACpE,CAAA;IAED,yFAAyF;IACzF,4CAA4C;IAC5C,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAA;IAEnD,iFAAiF;IACjF,IAAI,KAAK,KAAK,SAAS;QAAE,MAAM,CAAC,KAAK,GAAG,KAAK,CAAA;IAE7C,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,IAAe;IACvC,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAEzE,MAAM,MAAM,GAAW;QACrB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC;QACvC,GAAG;QACH,QAAQ;QACR,OAAO,EAAE,OAAO,IAAI,MAAM,CAAC,gBAAgB;QAC3C,QAAQ;QACR,IAAI;KACL,CAAA;IAED,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAA;IACnD,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAA;IAEnD,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,MAAc;IAClC,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,OAAO,CAAA;IAEpE,OAAO,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,gBAAgB,CAAA;AAC5D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,MAAc,EAAE,GAAW;IACnD,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;IAElD,OAAO,EAAE,KAAK,IAAI,IAAI,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;AACvD,CAAC;AAED,SAAS,IAAI,CAAC,MAAc,EAAE,KAAa;IACzC,OAAO,WAAW,CAAC,MAAM,CAAC,QAAS,EAAE,MAAM,CAAC,IAAK,CAAC,CAAC,KAAK,CAAC,CAAA;AAC3D,CAAC"}