@reventlessdev/reventless-core 3.0.0-alpha.174 → 3.0.0-alpha.176

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.
Files changed (88) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/package.json +7 -7
  3. package/src/ComponentType.res +4 -4
  4. package/src/ComponentType.res.mjs +6 -6
  5. package/src/RequestContext.res +45 -1
  6. package/src/RequestContext.res.mjs +12 -2
  7. package/src/ResourceAttribution.res +133 -0
  8. package/src/ResourceAttribution.res.mjs +96 -0
  9. package/src/adapter/Runtime/AggregateRuntime_Builder_Common.res +24 -5
  10. package/src/adapter/Runtime/AggregateRuntime_Builder_Common.res.mjs +9 -3
  11. package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res +6 -0
  12. package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res.mjs +3 -3
  13. package/src/adapter/Runtime/EventCollectorRuntime_Builder_PerEventCollector.res +6 -1
  14. package/src/adapter/Runtime/EventCollectorRuntime_Builder_PerEventCollector.res.mjs +3 -1
  15. package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res +25 -7
  16. package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res.mjs +11 -8
  17. package/src/adapter/Runtime/ExtensionPointRuntime_Builder_PerExtensionPoint.res +2 -0
  18. package/src/adapter/Runtime/ExtensionPointRuntime_Builder_PerExtensionPoint.res.mjs +1 -1
  19. package/src/adapter/Runtime/PluginRuntime_Builder_Micro.res +4 -0
  20. package/src/adapter/Runtime/PluginRuntime_Builder_Micro.res.mjs +2 -2
  21. package/src/adapter/Runtime/PluginRuntime_Builder_Single.res +4 -0
  22. package/src/adapter/Runtime/PluginRuntime_Builder_Single.res.mjs +2 -2
  23. package/src/adapter/Runtime/Runtime.res +49 -10
  24. package/src/adapter/Runtime/Runtime.res.mjs +22 -8
  25. package/src/admin/Platform_Admin.res +1 -1
  26. package/src/admin/Platform_Admin.res.mjs +8 -2
  27. package/src/components/Aggregate/Aggregate_Builder.res +10 -2
  28. package/src/components/Aggregate/Aggregate_Builder.res.mjs +8 -2
  29. package/src/components/AutomationSlice/AutomationSlice_Builder.res +12 -2
  30. package/src/components/AutomationSlice/AutomationSlice_Builder.res.mjs +8 -2
  31. package/src/components/CommandTopic/CommandTopic.res +5 -1
  32. package/src/components/CommandTopic/CommandTopic_Adapter.res +1 -0
  33. package/src/components/CommandTopic/CommandTopic_Builder.res +4 -4
  34. package/src/components/CommandTopic/CommandTopic_Builder.res.mjs +29 -30
  35. package/src/components/Counter/Counter_Builder.res +7 -1
  36. package/src/components/Counter/Counter_Builder.res.mjs +5 -2
  37. package/src/components/Dcb/Dcb_Builder.res +2 -2
  38. package/src/components/Dcb/Dcb_Builder.res.mjs +8 -2
  39. package/src/components/DcbEventLog/DcbEventLog_Builder.res +3 -0
  40. package/src/components/DcbEventLog/DcbEventLog_Builder.res.mjs +4 -1
  41. package/src/components/EventCollector/EventCollector.res +1 -0
  42. package/src/components/EventCollector/EventCollector_Adapter.res +1 -0
  43. package/src/components/EventCollector/EventCollector_Builder.res +4 -4
  44. package/src/components/EventCollector/EventCollector_Builder.res.mjs +2 -2
  45. package/src/components/EventLog/EventLog.res +5 -1
  46. package/src/components/EventLog/EventLog_Adapter.res +5 -1
  47. package/src/components/EventLog/EventLog_Builder.res +9 -4
  48. package/src/components/EventLog/EventLog_Builder.res.mjs +7 -8
  49. package/src/components/EventMapper/EventMapper_Builder.res +6 -1
  50. package/src/components/EventMapper/EventMapper_Builder.res.mjs +4 -1
  51. package/src/components/EventTopic/EventTopic.res +1 -0
  52. package/src/components/EventTopic/EventTopic_Adapter.res +1 -0
  53. package/src/components/EventTopic/EventTopic_Builder.res +4 -3
  54. package/src/components/EventTopic/EventTopic_Builder.res.mjs +2 -2
  55. package/src/components/ExtensionPoint/ExtensionPoint_Builder.res +11 -2
  56. package/src/components/ExtensionPoint/ExtensionPoint_Builder.res.mjs +8 -2
  57. package/src/components/InboundTranslationSlice/InboundTranslationSlice_Builder.res +6 -1
  58. package/src/components/InboundTranslationSlice/InboundTranslationSlice_Builder.res.mjs +4 -1
  59. package/src/components/OutboundTranslationSlice/OutboundTranslationSlice_Builder.res +12 -2
  60. package/src/components/OutboundTranslationSlice/OutboundTranslationSlice_Builder.res.mjs +8 -2
  61. package/src/components/QueryDb/QueryDb.res +1 -0
  62. package/src/components/QueryDb/QueryDb_Adapter.res +1 -0
  63. package/src/components/QueryDb/QueryDb_Builder.res +4 -3
  64. package/src/components/QueryDb/QueryDb_Builder.res.mjs +2 -2
  65. package/src/components/ReadModel/ReadModel_Builder.res +12 -2
  66. package/src/components/ReadModel/ReadModel_Builder.res.mjs +8 -2
  67. package/src/components/SideEffectHandler/SideEffectHandler_Builder.res +6 -1
  68. package/src/components/SideEffectHandler/SideEffectHandler_Builder.res.mjs +4 -1
  69. package/src/components/StateViewSlice/StateViewSlice_Builder.res +12 -2
  70. package/src/components/StateViewSlice/StateViewSlice_Builder.res.mjs +8 -2
  71. package/src/plugin/component/Plugin_Builder.res +8 -2
  72. package/src/plugin/component/Plugin_Builder.res.mjs +4 -1
  73. package/src/plugin/component/Plugin_Helpers.res +1 -1
  74. package/src/plugin/component/Plugin_Helpers.res.mjs +4 -1
  75. package/src/plugin/connect/PluginExtensionPoint_Plugin.res +26 -12
  76. package/src/plugin/connect/PluginExtensionPoint_Plugin.res.mjs +8 -8
  77. package/src/util/Interstack.res +1 -1
  78. package/src/util/Interstack.res.mjs +3 -3
  79. package/src/util/Interstack.resi +1 -1
  80. package/src/util/Util_StackRefs.res +2 -2
  81. package/src/util/Util_StackRefs.res.mjs +4 -4
  82. package/tests/ResourceAttributionTest.res +70 -0
  83. package/tests/aggregate/AggregateCacheTest.res +1 -1
  84. package/tests/aggregate/AggregateConflictTest.res +1 -1
  85. package/tests/aggregate/AggregateFixtures.res +1 -1
  86. package/tests/aggregate/AggregateSnapshotTest.res +1 -1
  87. package/tests/eventlog/EventLogFixtures.res +1 -1
  88. package/tests/logger/LogFormatTest.res +43 -0
@@ -14,7 +14,7 @@ function Make(RuntimeEnvironment) {
14
14
  let timeout = timeoutOpt !== undefined ? timeoutOpt : 30;
15
15
  let resource = Component$ReventlessCore.toPulumiResource(commandGenerator);
16
16
  let name = ComponentType$ReventlessCore.nameOpt(resource.__name, CommandGenerator$ReventlessCore.componentType);
17
- return connect(RuntimeEnvironment.make(name, handler.apply(handler => Runtime$ReventlessCore.runEffectHandler(RuntimeEnvironment.extractCorrelationId, RuntimeEnvironment.extractCausationId, name, undefined, RuntimeEnvironment.asEffectHandler(handler))), memorySize, timeout, {
17
+ return connect(RuntimeEnvironment.make(name, handler.apply(handler => Runtime$ReventlessCore.runEffectHandler(RuntimeEnvironment.extractCorrelationId, RuntimeEnvironment.extractCausationId, RuntimeEnvironment.extractSentTimestamp, RuntimeEnvironment.extractRetryCount, name, undefined, RuntimeEnvironment.asEffectHandler(handler))), memorySize, timeout, {
18
18
  parent: resource
19
19
  }));
20
20
  };
@@ -23,7 +23,7 @@ function Make(RuntimeEnvironment) {
23
23
  let timeout = timeoutOpt !== undefined ? timeoutOpt : 30;
24
24
  let resource = Component$ReventlessCore.toPulumiResource(commandTopic);
25
25
  let name = ComponentType$ReventlessCore.nameOpt(resource.__name, CommandTopic$ReventlessCore.componentType);
26
- return connect(RuntimeEnvironment.make(name, handler.apply(handler => Runtime$ReventlessCore.runEffectHandler(RuntimeEnvironment.extractCorrelationId, RuntimeEnvironment.extractCausationId, name, undefined, RuntimeEnvironment.asEffectHandler(handler))), memorySize, timeout, {
26
+ return connect(RuntimeEnvironment.make(name, handler.apply(handler => Runtime$ReventlessCore.runEffectHandler(RuntimeEnvironment.extractCorrelationId, RuntimeEnvironment.extractCausationId, RuntimeEnvironment.extractSentTimestamp, RuntimeEnvironment.extractRetryCount, name, undefined, RuntimeEnvironment.asEffectHandler(handler))), memorySize, timeout, {
27
27
  parent: resource
28
28
  }));
29
29
  };
@@ -36,7 +36,7 @@ function Make(RuntimeEnvironment) {
36
36
  let opts = {
37
37
  parent: opts_parent
38
38
  };
39
- let runtime = RuntimeEnvironment.make(name, handler.apply(handler => Runtime$ReventlessCore.runEffectHandler(RuntimeEnvironment.extractCorrelationId, RuntimeEnvironment.extractCausationId, name, undefined, RuntimeEnvironment.asEffectHandler(handler))), memorySize, timeout, opts);
39
+ let runtime = RuntimeEnvironment.make(name, handler.apply(handler => Runtime$ReventlessCore.runEffectHandler(RuntimeEnvironment.extractCorrelationId, RuntimeEnvironment.extractCausationId, RuntimeEnvironment.extractSentTimestamp, RuntimeEnvironment.extractRetryCount, name, undefined, RuntimeEnvironment.asEffectHandler(handler))), memorySize, timeout, opts);
40
40
  EventCollectorChannel.connect(name, [{
41
41
  channel: eventCollector.channel,
42
42
  eventTopics: eventTopics,
@@ -22,6 +22,9 @@ module Make = (
22
22
  ) => {
23
23
  let resource = eventCollector->Component.toPulumiResource
24
24
  let name = resource.name->ComponentType.nameOpt(EventCollector.componentType)
25
+ // Same `comp` shape as the shared-runtime dispatchers, so a log filter reads the
26
+ // same whichever deployment strategy hosts the collector.
27
+ let comp = `EventCollector(${resource.name->Option.getOr("Unnamed")})`
25
28
  let opts = {Pulumi.ComponentResource.parent: resource}
26
29
  let runtime = RuntimeEnvironment.make(
27
30
  ~name,
@@ -31,7 +34,9 @@ module Make = (
31
34
  ->Runtime.runEffectHandler(
32
35
  ~extractCorrelationId=RuntimeEnvironment.extractCorrelationId,
33
36
  ~extractCausationId=RuntimeEnvironment.extractCausationId,
34
- ~comp=name,
37
+ ~extractSentTimestamp=RuntimeEnvironment.extractSentTimestamp,
38
+ ~extractRetryCount=RuntimeEnvironment.extractRetryCount,
39
+ ~comp,
35
40
  )
36
41
  ),
37
42
  ~memorySize,
@@ -1,5 +1,6 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
+ import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
3
4
  import * as Runtime$ReventlessCore from "./Runtime.res.mjs";
4
5
  import * as Component$ReventlessCore from "../../components/Component.res.mjs";
5
6
  import * as ComponentType$ReventlessCore from "../../ComponentType.res.mjs";
@@ -12,11 +13,12 @@ function Make(RuntimeEnvironment) {
12
13
  let timeout = timeoutOpt !== undefined ? timeoutOpt : 30;
13
14
  let resource = Component$ReventlessCore.toPulumiResource(eventCollector);
14
15
  let name = ComponentType$ReventlessCore.nameOpt(resource.__name, EventCollector$ReventlessCore.componentType);
16
+ let comp = `EventCollector(` + Stdlib_Option.getOr(resource.__name, "Unnamed") + `)`;
15
17
  let opts_parent = resource;
16
18
  let opts = {
17
19
  parent: opts_parent
18
20
  };
19
- let runtime = RuntimeEnvironment.make(name, handler.apply(handler => Runtime$ReventlessCore.runEffectHandler(RuntimeEnvironment.extractCorrelationId, RuntimeEnvironment.extractCausationId, name, undefined, RuntimeEnvironment.asEffectHandler(handler))), memorySize, timeout, {
21
+ let runtime = RuntimeEnvironment.make(name, handler.apply(handler => Runtime$ReventlessCore.runEffectHandler(RuntimeEnvironment.extractCorrelationId, RuntimeEnvironment.extractCausationId, RuntimeEnvironment.extractSentTimestamp, RuntimeEnvironment.extractRetryCount, comp, undefined, RuntimeEnvironment.asEffectHandler(handler))), memorySize, timeout, {
20
22
  parent: resource
21
23
  });
22
24
  EventCollectorChannel.connect(name, [{
@@ -34,16 +34,24 @@ module Make = (
34
34
  maxTimeout: 0,
35
35
  })
36
36
  type effectHandler = Runtime.effectHandler<RuntimeEnvironment.event, context, unit, string>
37
- let eventCollectorHandlers: dict<array<effectHandler>> = Dict.make()
37
+ // `comp` is the *element's* log component, resolved where the handler is registered
38
+ // (the event collector's own resource is in hand there). Keeping it next to the
39
+ // handler is what makes every collector hosted in this one runtime separable by
40
+ // field — the runtime-group name would be identical for all of them.
41
+ type registeredHandler = {comp: string, handler: effectHandler}
42
+ let eventCollectorHandlers: dict<array<registeredHandler>> = Dict.make()
38
43
 
39
44
  let eventCollectorHandler = parentName =>
40
45
  async (event: RuntimeEnvironment.event, context) => {
41
46
  let correlationId = event->RuntimeEnvironment.extractCorrelationId
42
47
  let causationId = event->RuntimeEnvironment.extractCausationId
43
- let comp = `EventCollectorRuntime(${parentName})`
48
+ let timestamp = event->RuntimeEnvironment.extractSentTimestamp
49
+ let retryCount = event->RuntimeEnvironment.extractRetryCount
50
+ // Group-level comp — used only for this dispatcher's own bookkeeping lines,
51
+ // which describe the runtime group rather than any one collector.
52
+ let groupComp = `EventCollectorRuntime(${parentName})`
44
53
  // Shared dispatch helper annotates correlationId / comp / causationId so the
45
54
  // application handler's own log lines carry them (see Runtime.runEffect).
46
- let runEffect = effect => Runtime.runEffect(~correlationId?, ~causationId?, ~comp, effect)
47
55
  let _ = await event
48
56
  ->RuntimeEnvironment.groupBySource
49
57
  ->Dict.toArray
@@ -52,13 +60,22 @@ module Make = (
52
60
  | Some(handlers) =>
53
61
  let count = handlers->Array.length->Int.toString
54
62
  EffectLogger.logDebug(
55
- ~comp,
63
+ ~comp=groupComp,
56
64
  `found ${count} handler(s) for ${urn}`,
57
65
  )->Effect.runSync
58
66
  let _ = await handlers
59
- ->Array.map(handler => runEffect(handler(event, context)))
67
+ ->Array.map(({comp, handler}) =>
68
+ Runtime.runEffect(
69
+ ~correlationId?,
70
+ ~causationId?,
71
+ ~comp,
72
+ ~timestamp?,
73
+ ~retryCount?,
74
+ handler(event, context),
75
+ )
76
+ )
60
77
  ->Promise.all
61
- | None => EffectLogger.logWarn(~comp, `no handler found: ${urn}`)->Effect.runSync
78
+ | None => EffectLogger.logWarn(~comp=groupComp, `no handler found: ${urn}`)->Effect.runSync
62
79
  }
63
80
  })
64
81
  ->Promise.all
@@ -155,11 +172,12 @@ module Make = (
155
172
  ~comp="EventCollectorRuntime",
156
173
  `forEventCollector ${eventCollectorName}: set handler for ${urns->Array.join(", ")}`,
157
174
  )
175
+ let comp = `EventCollector(${eventCollectorName})`
158
176
  urns->Array.map(urn => {
159
177
  let handlers = eventCollectorHandlers->Dict.get(urn)->Option.getOr([])
160
178
  eventCollectorHandlers->Dict.set(
161
179
  urn,
162
- handlers->Array.concat([handler->RuntimeEnvironment.asEffectHandler]),
180
+ handlers->Array.concat([{comp, handler: handler->RuntimeEnvironment.asEffectHandler}]),
163
181
  )
164
182
  })
165
183
  })
@@ -30,20 +30,19 @@ function Make(RuntimeEnvironment) {
30
30
  let eventCollectorHandler = parentName => (async (event, context) => {
31
31
  let correlationId = RuntimeEnvironment.extractCorrelationId(event);
32
32
  let causationId = RuntimeEnvironment.extractCausationId(event);
33
- let comp = `EventCollectorRuntime(` + parentName + `)`;
33
+ let timestamp = RuntimeEnvironment.extractSentTimestamp(event);
34
+ let retryCount = RuntimeEnvironment.extractRetryCount(event);
35
+ let groupComp = `EventCollectorRuntime(` + parentName + `)`;
34
36
  await Promise.all(Object.entries(RuntimeEnvironment.groupBySource(event)).map(async param => {
35
37
  let event = param[1];
36
38
  let urn = param[0];
37
39
  let handlers = eventCollectorHandlers[urn];
38
40
  if (handlers === undefined) {
39
- return Effect.runSync(EffectLogger$ReventlessCore.logWarn(comp, undefined, `no handler found: ` + urn));
41
+ return Effect.runSync(EffectLogger$ReventlessCore.logWarn(groupComp, undefined, `no handler found: ` + urn));
40
42
  }
41
43
  let count = handlers.length.toString();
42
- Effect.runSync(EffectLogger$ReventlessCore.logDebug(comp, undefined, `found ` + count + ` handler(s) for ` + urn));
43
- await Promise.all(handlers.map(handler => {
44
- let effect = handler(event, context);
45
- return Runtime$ReventlessCore.runEffect(correlationId, causationId, comp, undefined, undefined, undefined, effect);
46
- }));
44
+ Effect.runSync(EffectLogger$ReventlessCore.logDebug(groupComp, undefined, `found ` + count + ` handler(s) for ` + urn));
45
+ await Promise.all(handlers.map(param => Runtime$ReventlessCore.runEffect(correlationId, causationId, param.comp, undefined, timestamp, retryCount, undefined, undefined, param.handler(event, context))));
47
46
  }));
48
47
  });
49
48
  let validateParent = parent => {
@@ -108,9 +107,13 @@ function Make(RuntimeEnvironment) {
108
107
  let handler = param[2];
109
108
  let urns = param[1];
110
109
  log.debug("EventCollectorRuntime", undefined, `forEventCollector ` + eventCollectorName + `: set handler for ` + urns.join(", "));
110
+ let comp = `EventCollector(` + eventCollectorName + `)`;
111
111
  return urns.map(urn => {
112
112
  let handlers = Stdlib_Option.getOr(eventCollectorHandlers[urn], []);
113
- eventCollectorHandlers[urn] = handlers.concat([RuntimeEnvironment.asEffectHandler(handler)]);
113
+ eventCollectorHandlers[urn] = handlers.concat([{
114
+ comp: comp,
115
+ handler: RuntimeEnvironment.asEffectHandler(handler)
116
+ }]);
114
117
  });
115
118
  });
116
119
  };
@@ -31,6 +31,8 @@ module Make = (
31
31
  ->Runtime.runEffectHandler(
32
32
  ~extractCorrelationId=RuntimeEnvironment.extractCorrelationId,
33
33
  ~extractCausationId=RuntimeEnvironment.extractCausationId,
34
+ ~extractSentTimestamp=RuntimeEnvironment.extractSentTimestamp,
35
+ ~extractRetryCount=RuntimeEnvironment.extractRetryCount,
34
36
  ~comp=name,
35
37
  )
36
38
  ),
@@ -12,7 +12,7 @@ function Make(RuntimeEnvironment) {
12
12
  let timeout = timeoutOpt !== undefined ? timeoutOpt : 30;
13
13
  let resource = Component$ReventlessCore.toPulumiResource(commandTopic);
14
14
  let name = ComponentType$ReventlessCore.nameOpt(resource.__name, CommandTopic$ReventlessCore.componentType);
15
- return connect(RuntimeEnvironment.make(name, handler.apply(handler => Runtime$ReventlessCore.runEffectHandler(RuntimeEnvironment.extractCorrelationId, RuntimeEnvironment.extractCausationId, name, undefined, RuntimeEnvironment.asEffectHandler(handler))), memorySize, timeout, {
15
+ return connect(RuntimeEnvironment.make(name, handler.apply(handler => Runtime$ReventlessCore.runEffectHandler(RuntimeEnvironment.extractCorrelationId, RuntimeEnvironment.extractCausationId, RuntimeEnvironment.extractSentTimestamp, RuntimeEnvironment.extractRetryCount, name, undefined, RuntimeEnvironment.asEffectHandler(handler))), memorySize, timeout, {
16
16
  parent: resource
17
17
  }));
18
18
  };
@@ -31,6 +31,8 @@ module Make = (
31
31
  ->Runtime.runEffectHandler(
32
32
  ~extractCorrelationId=RuntimeEnvironment.extractCorrelationId,
33
33
  ~extractCausationId=RuntimeEnvironment.extractCausationId,
34
+ ~extractSentTimestamp=RuntimeEnvironment.extractSentTimestamp,
35
+ ~extractRetryCount=RuntimeEnvironment.extractRetryCount,
34
36
  ~comp=name,
35
37
  )
36
38
  ),
@@ -85,6 +87,8 @@ module Make = (
85
87
  ->Runtime.runEffectHandler(
86
88
  ~extractCorrelationId=RuntimeEnvironment.extractCorrelationId,
87
89
  ~extractCausationId=RuntimeEnvironment.extractCausationId,
90
+ ~extractSentTimestamp=RuntimeEnvironment.extractSentTimestamp,
91
+ ~extractRetryCount=RuntimeEnvironment.extractRetryCount,
88
92
  ~comp=name,
89
93
  )
90
94
  ),
@@ -18,7 +18,7 @@ function Make(RuntimeEnvironment) {
18
18
  let opts = {
19
19
  parent: opts_parent
20
20
  };
21
- let runtime = RuntimeEnvironment.make(name, handler.apply(handler => Runtime$ReventlessCore.runEffectHandler(RuntimeEnvironment.extractCorrelationId, RuntimeEnvironment.extractCausationId, name, undefined, RuntimeEnvironment.asEffectHandler(handler))), memorySize, timeout, {
21
+ let runtime = RuntimeEnvironment.make(name, handler.apply(handler => Runtime$ReventlessCore.runEffectHandler(RuntimeEnvironment.extractCorrelationId, RuntimeEnvironment.extractCausationId, RuntimeEnvironment.extractSentTimestamp, RuntimeEnvironment.extractRetryCount, name, undefined, RuntimeEnvironment.asEffectHandler(handler))), memorySize, timeout, {
22
22
  parent: resource
23
23
  });
24
24
  EventCollectorChannel.connect(name, [{
@@ -41,7 +41,7 @@ function Make(RuntimeEnvironment) {
41
41
  let timeout = timeoutOpt !== undefined ? timeoutOpt : 30;
42
42
  let resource = Component$ReventlessCore.toPulumiResource(dcbCommandTopic);
43
43
  let name = ComponentType$ReventlessCore.nameOpt(resource.__name, CommandTopic$ReventlessCore.componentType);
44
- return connect(RuntimeEnvironment.make(name, handler.apply(handler => Runtime$ReventlessCore.runEffectHandler(RuntimeEnvironment.extractCorrelationId, RuntimeEnvironment.extractCausationId, name, undefined, RuntimeEnvironment.asEffectHandler(handler))), memorySize, timeout, {
44
+ return connect(RuntimeEnvironment.make(name, handler.apply(handler => Runtime$ReventlessCore.runEffectHandler(RuntimeEnvironment.extractCorrelationId, RuntimeEnvironment.extractCausationId, RuntimeEnvironment.extractSentTimestamp, RuntimeEnvironment.extractRetryCount, name, undefined, RuntimeEnvironment.asEffectHandler(handler))), memorySize, timeout, {
45
45
  parent: resource
46
46
  }));
47
47
  };
@@ -31,6 +31,8 @@ module Make = (
31
31
  ->Runtime.runEffectHandler(
32
32
  ~extractCorrelationId=RuntimeEnvironment.extractCorrelationId,
33
33
  ~extractCausationId=RuntimeEnvironment.extractCausationId,
34
+ ~extractSentTimestamp=RuntimeEnvironment.extractSentTimestamp,
35
+ ~extractRetryCount=RuntimeEnvironment.extractRetryCount,
34
36
  ~comp=name,
35
37
  )
36
38
  ),
@@ -85,6 +87,8 @@ module Make = (
85
87
  ->Runtime.runEffectHandler(
86
88
  ~extractCorrelationId=RuntimeEnvironment.extractCorrelationId,
87
89
  ~extractCausationId=RuntimeEnvironment.extractCausationId,
90
+ ~extractSentTimestamp=RuntimeEnvironment.extractSentTimestamp,
91
+ ~extractRetryCount=RuntimeEnvironment.extractRetryCount,
88
92
  ~comp=name,
89
93
  )
90
94
  ),
@@ -18,7 +18,7 @@ function Make(RuntimeEnvironment) {
18
18
  let opts = {
19
19
  parent: opts_parent
20
20
  };
21
- let runtime = RuntimeEnvironment.make(name, handler.apply(handler => Runtime$ReventlessCore.runEffectHandler(RuntimeEnvironment.extractCorrelationId, RuntimeEnvironment.extractCausationId, name, undefined, RuntimeEnvironment.asEffectHandler(handler))), memorySize, timeout, {
21
+ let runtime = RuntimeEnvironment.make(name, handler.apply(handler => Runtime$ReventlessCore.runEffectHandler(RuntimeEnvironment.extractCorrelationId, RuntimeEnvironment.extractCausationId, RuntimeEnvironment.extractSentTimestamp, RuntimeEnvironment.extractRetryCount, name, undefined, RuntimeEnvironment.asEffectHandler(handler))), memorySize, timeout, {
22
22
  parent: resource
23
23
  });
24
24
  EventCollectorChannel.connect(name, [{
@@ -41,7 +41,7 @@ function Make(RuntimeEnvironment) {
41
41
  let timeout = timeoutOpt !== undefined ? timeoutOpt : 30;
42
42
  let resource = Component$ReventlessCore.toPulumiResource(dcbCommandTopic);
43
43
  let name = ComponentType$ReventlessCore.nameOpt(resource.__name, CommandTopic$ReventlessCore.componentType);
44
- return connect(RuntimeEnvironment.make(name, handler.apply(handler => Runtime$ReventlessCore.runEffectHandler(RuntimeEnvironment.extractCorrelationId, RuntimeEnvironment.extractCausationId, name, undefined, RuntimeEnvironment.asEffectHandler(handler))), memorySize, timeout, {
44
+ return connect(RuntimeEnvironment.make(name, handler.apply(handler => Runtime$ReventlessCore.runEffectHandler(RuntimeEnvironment.extractCorrelationId, RuntimeEnvironment.extractCausationId, RuntimeEnvironment.extractSentTimestamp, RuntimeEnvironment.extractRetryCount, name, undefined, RuntimeEnvironment.asEffectHandler(handler))), memorySize, timeout, {
45
45
  parent: resource
46
46
  }));
47
47
  };
@@ -18,6 +18,8 @@ let annotateInvocation = (
18
18
  ~causationId=?,
19
19
  ~comp=?,
20
20
  ~pluginName=?,
21
+ ~timestamp=?,
22
+ ~retryCount=?,
21
23
  ~identity=?,
22
24
  ~claims=?,
23
25
  ) => {
@@ -34,10 +36,20 @@ let annotateInvocation = (
34
36
  | Some(v) => eff->Effect.annotateLogs(key, v)
35
37
  | None => eff
36
38
  }
39
+ // Only a redelivery is annotated: a constant "1" on every line is noise, and
40
+ // its absence is what makes `retryCount > 1` a usable filter. `timestamp` is
41
+ // never annotated — it is a context field for computing latency, not a key
42
+ // anyone filters on.
43
+ let annotateRetry = eff =>
44
+ switch retryCount {
45
+ | Some(count) if count > 1 => eff->Effect.annotateLogs("retryCount", count->Int.toString)
46
+ | _ => eff
47
+ }
37
48
  effect
38
49
  ->Effect.annotateLogs("correlationId", cid)
39
50
  ->annotateOpt("comp", comp)
40
51
  ->annotateOpt("causationId", causationId)
52
+ ->annotateRetry
41
53
  ->Effect.provideService(
42
54
  RequestContext.tag,
43
55
  RequestContext.make(
@@ -45,6 +57,8 @@ let annotateInvocation = (
45
57
  ~causationId?,
46
58
  ~component=?comp,
47
59
  ~pluginName=?resolvedPlugin,
60
+ ~timestamp?,
61
+ ~retryCount?,
48
62
  ~identity?,
49
63
  ~claims?,
50
64
  ),
@@ -59,12 +73,23 @@ let runEffect = (
59
73
  ~causationId=?,
60
74
  ~comp=?,
61
75
  ~pluginName=?,
76
+ ~timestamp=?,
77
+ ~retryCount=?,
62
78
  ~identity=?,
63
79
  ~claims=?,
64
80
  effect,
65
81
  ) =>
66
82
  effect
67
- ->annotateInvocation(~correlationId?, ~causationId?, ~comp?, ~pluginName?, ~identity?, ~claims?)
83
+ ->annotateInvocation(
84
+ ~correlationId?,
85
+ ~causationId?,
86
+ ~comp?,
87
+ ~pluginName?,
88
+ ~timestamp?,
89
+ ~retryCount?,
90
+ ~identity?,
91
+ ~claims?,
92
+ )
68
93
  ->Effect.runPromise
69
94
 
70
95
  // Convert an effectHandler to an eventHandler at build time, annotating the
@@ -76,21 +101,31 @@ let runEffect = (
76
101
  let runEffectHandler = (
77
102
  ~extractCorrelationId: option<'event => option<string>>=?,
78
103
  ~extractCausationId: option<'event => option<string>>=?,
104
+ ~extractSentTimestamp: option<'event => option<float>>=?,
105
+ ~extractRetryCount: option<'event => option<int>>=?,
79
106
  ~comp=?,
80
107
  ~pluginName=?,
81
108
  handler: effectHandler<'event, 'context, 'result, 'error>,
82
109
  ): eventHandler<'event, 'context, 'result> =>
83
110
  (event, ctx) => {
84
- let correlationId = switch extractCorrelationId {
85
- | Some(f) => f(event)
86
- | None => None
87
- }
88
- let causationId = switch extractCausationId {
89
- | Some(f) => f(event)
90
- | None => None
91
- }
111
+ let extract = (f, event) =>
112
+ switch f {
113
+ | Some(f) => f(event)
114
+ | None => None
115
+ }
116
+ let correlationId = extractCorrelationId->extract(event)
117
+ let causationId = extractCausationId->extract(event)
118
+ let timestamp = extractSentTimestamp->extract(event)
119
+ let retryCount = extractRetryCount->extract(event)
92
120
  handler(event, ctx)
93
- ->annotateInvocation(~correlationId?, ~causationId?, ~comp?, ~pluginName?)
121
+ ->annotateInvocation(
122
+ ~correlationId?,
123
+ ~causationId?,
124
+ ~comp?,
125
+ ~pluginName?,
126
+ ~timestamp?,
127
+ ~retryCount?,
128
+ )
94
129
  ->Effect.runPromise
95
130
  }
96
131
 
@@ -115,6 +150,10 @@ module type Environment = {
115
150
  let groupBySource: event => dict<event>
116
151
  let extractCorrelationId: event => option<string>
117
152
  let extractCausationId: event => option<string>
153
+ // Transport-level delivery facts, for RequestContext.timestamp / .retryCount.
154
+ // `None` where the transport carries no such notion (see each implementation).
155
+ let extractSentTimestamp: event => option<float>
156
+ let extractRetryCount: event => option<int>
118
157
  let asEventHandler: 'a => eventHandler<event, context, 'result>
119
158
  let asEffectHandler: 'a => effectHandler<event, context, 'result, 'error>
120
159
  }
@@ -5,7 +5,7 @@ import * as Effect from "effect/Effect";
5
5
  import * as LogPrefix$Reventless from "@reventlessdev/reventless-spec/src/LogPrefix.res.mjs";
6
6
  import * as RequestContext$ReventlessCore from "../../RequestContext.res.mjs";
7
7
 
8
- function annotateInvocation(effect, correlationId, causationId, comp, pluginName, identity, claims) {
8
+ function annotateInvocation(effect, correlationId, causationId, comp, pluginName, timestamp, retryCount, identity, claims) {
9
9
  let cid = Stdlib_Option.getOr(correlationId, "unknown");
10
10
  let resolvedPlugin = pluginName !== undefined ? pluginName : LogPrefix$Reventless.resolvePlugin(comp, undefined);
11
11
  let annotateOpt = (eff, key, value) => {
@@ -15,18 +15,32 @@ function annotateInvocation(effect, correlationId, causationId, comp, pluginName
15
15
  return eff;
16
16
  }
17
17
  };
18
- return Effect.provideService(annotateOpt(annotateOpt(Effect.annotateLogs(effect, "correlationId", cid), "comp", comp), "causationId", causationId), RequestContext$ReventlessCore.tag, RequestContext$ReventlessCore.make(cid, causationId, comp, resolvedPlugin, identity, claims));
18
+ let annotateRetry = eff => {
19
+ if (retryCount !== undefined && retryCount > 1) {
20
+ return Effect.annotateLogs(eff, "retryCount", retryCount.toString());
21
+ } else {
22
+ return eff;
23
+ }
24
+ };
25
+ return Effect.provideService(annotateRetry(annotateOpt(annotateOpt(Effect.annotateLogs(effect, "correlationId", cid), "comp", comp), "causationId", causationId)), RequestContext$ReventlessCore.tag, RequestContext$ReventlessCore.make(cid, causationId, comp, resolvedPlugin, timestamp, retryCount, identity, claims));
19
26
  }
20
27
 
21
- function runEffect(correlationId, causationId, comp, pluginName, identity, claims, effect) {
22
- return Effect.runPromise(annotateInvocation(effect, correlationId, causationId, comp, pluginName, identity, claims));
28
+ function runEffect(correlationId, causationId, comp, pluginName, timestamp, retryCount, identity, claims, effect) {
29
+ return Effect.runPromise(annotateInvocation(effect, correlationId, causationId, comp, pluginName, timestamp, retryCount, identity, claims));
23
30
  }
24
31
 
25
- function runEffectHandler(extractCorrelationId, extractCausationId, comp, pluginName, handler) {
32
+ function runEffectHandler(extractCorrelationId, extractCausationId, extractSentTimestamp, extractRetryCount, comp, pluginName, handler) {
26
33
  return (event, ctx) => {
27
- let correlationId = extractCorrelationId !== undefined ? extractCorrelationId(event) : undefined;
28
- let causationId = extractCausationId !== undefined ? extractCausationId(event) : undefined;
29
- return Effect.runPromise(annotateInvocation(handler(event, ctx), correlationId, causationId, comp, pluginName, undefined, undefined));
34
+ let extract = (f, event) => {
35
+ if (f !== undefined) {
36
+ return f(event);
37
+ }
38
+ };
39
+ let correlationId = extract(extractCorrelationId, event);
40
+ let causationId = extract(extractCausationId, event);
41
+ let timestamp = extract(extractSentTimestamp, event);
42
+ let retryCount = extract(extractRetryCount, event);
43
+ return Effect.runPromise(annotateInvocation(handler(event, ctx), correlationId, causationId, comp, pluginName, timestamp, retryCount, undefined, undefined));
30
44
  };
31
45
  }
32
46
 
@@ -53,7 +53,7 @@ module Make = (
53
53
  ) => {
54
54
  module AdminEventCollector = EventCollector_Builder.Make(RE, ECC)
55
55
  let make = (~name, ~eventTopics, ~opts) => {
56
- let eventCollector = AdminEventCollector.make(~name, ~eventTopics, ~opts)
56
+ let eventCollector = AdminEventCollector.make(~name, ~eventTopics, ~owner={kind: ComponentType.Plugin, name}, ~opts)
57
57
  let eventCollectorOutputs = eventCollector->Component.outputs
58
58
  (eventCollector, eventCollectorOutputs)
59
59
  }
@@ -24,7 +24,10 @@ function Make(RuntimeEnvironment) {
24
24
  let MakeEventCollectorHelper = RE => (ECC => (RB => {
25
25
  let AdminEventCollector = EventCollector_Builder$ReventlessCore.Make(RE)(ECC);
26
26
  let make = (name, eventTopics, opts) => {
27
- let eventCollector = AdminEventCollector.make(name, eventTopics, opts);
27
+ let eventCollector = AdminEventCollector.make(name, eventTopics, {
28
+ kind: "Plugin",
29
+ name: name
30
+ }, opts);
28
31
  let eventCollectorOutputs = Component$ReventlessCore.outputs(eventCollector);
29
32
  return [
30
33
  eventCollector,
@@ -174,7 +177,10 @@ function Make(RuntimeEnvironment) {
174
177
  let eventTopics = Aggregate$ReventlessCore.filterEventTopics(aggregatesOutputs, aggregateNames);
175
178
  let AdminEventCollector = EventCollector_Builder$ReventlessCore.Make(RuntimeEnvironment)(EventCollectorChannel);
176
179
  let make = (name, eventTopics, opts) => {
177
- let eventCollector = AdminEventCollector.make(name, eventTopics, opts);
180
+ let eventCollector = AdminEventCollector.make(name, eventTopics, {
181
+ kind: "Plugin",
182
+ name: name
183
+ }, opts);
178
184
  let eventCollectorOutputs = Component$ReventlessCore.outputs(eventCollector);
179
185
  return [
180
186
  eventCollector,
@@ -79,7 +79,11 @@ module Make = (
79
79
  let eventLog = eventLogOps
80
80
  },
81
81
  )
82
- let commandTopic = SpecificCommandTopic.make(~name, ~opts)
82
+ let commandTopic = SpecificCommandTopic.make(
83
+ ~name,
84
+ ~owner={kind: ComponentType.Aggregate, name: Spec.name},
85
+ ~opts,
86
+ )
83
87
  let handler = SpecificCommandTopic.makeHandler(
84
88
  ~commandTopic,
85
89
  ~commandsHandler=AggregateCallback.handleCommands,
@@ -148,7 +152,11 @@ module Make = (
148
152
  let memorySize = ReventlessInfra.RuntimeHints.resolveMemory(runtime, ~default=1024)
149
153
  let timeout = ReventlessInfra.RuntimeHints.resolveTimeout(runtime, ~default=30)
150
154
 
151
- let eventLog = SpecificEventLog.make(~name, ~opts)
155
+ let eventLog = SpecificEventLog.make(
156
+ ~name,
157
+ ~owner={kind: ComponentType.Aggregate, name: Spec.name},
158
+ ~opts,
159
+ )
152
160
  let commandTopic = eventLog->createCommandTopic(name, opts, ~memorySize, ~timeout)
153
161
  let commandGenerator = commandTopic->createCommandGenerator(~api, name, opts, ~memorySize, ~timeout)
154
162
 
@@ -36,7 +36,10 @@ function Make(Spec) {
36
36
  EventLog: SpecificEventLog,
37
37
  eventLog: eventLogOps
38
38
  });
39
- let commandTopic = SpecificCommandTopic.make(name, opts);
39
+ let commandTopic = SpecificCommandTopic.make(name, {
40
+ kind: "Aggregate",
41
+ name: Spec.name
42
+ }, opts);
40
43
  let handler = SpecificCommandTopic.makeHandler(commandTopic, AggregateCallback.handleCommands);
41
44
  let eventLog$1 = Component$ReventlessCore.outputs(eventLog);
42
45
  let resources = [
@@ -72,7 +75,10 @@ function Make(Spec) {
72
75
  let name = ComponentType$ReventlessCore.name(extra$1, Aggregate$ReventlessCore.componentType);
73
76
  let memorySize = RuntimeHints$ReventlessInfra.resolveMemory(runtime, 1024);
74
77
  let timeout = RuntimeHints$ReventlessInfra.resolveTimeout(runtime, 30);
75
- let eventLog = SpecificEventLog.make(name, opts);
78
+ let eventLog = SpecificEventLog.make(name, {
79
+ kind: "Aggregate",
80
+ name: Spec.name
81
+ }, opts);
76
82
  let commandTopic = createCommandTopic(eventLog, name, opts, memorySize, timeout);
77
83
  let commandGenerator = createCommandGenerator(commandTopic, api, name, opts, memorySize, timeout);
78
84
  Component$ReventlessCore.setOperations(extra, Output$Pulumi.flatMap(commandTopic, commandTopic => Component$ReventlessCore.operations(commandTopic).apply(param => ({
@@ -89,7 +89,12 @@ module Make = (
89
89
  let memorySize = ReventlessInfra.RuntimeHints.resolveMemory(runtime, ~default=1024)
90
90
  let timeout = ReventlessInfra.RuntimeHints.resolveTimeout(runtime, ~default=30)
91
91
 
92
- let queryDb = SpecificQueryDb.make(~api=Api.api(), ~apiRole=Api.apiRole(), ~opts)
92
+ let queryDb = SpecificQueryDb.make(
93
+ ~api=Api.api(),
94
+ ~apiRole=Api.apiRole(),
95
+ ~owner={kind: ComponentType.AutomationSlice, name: Spec.name},
96
+ ~opts,
97
+ )
93
98
 
94
99
  // Fail-fast: every Mapping.sourceName must resolve to a topic in
95
100
  // `allEventTopics`. Catches Aggregate-name typos and DCB-source-name
@@ -125,7 +130,12 @@ module Make = (
125
130
  (queryDb->Component.operations, publishJsons)
126
131
  ->Pulumi.Output.all2
127
132
  ->Pulumi.Output.apply(((queryDbOps, publishJsonsFn)) => {
128
- let ec = SpecificEventCollector.make(~name=Spec.name, ~eventTopics, ~opts)
133
+ let ec = SpecificEventCollector.make(
134
+ ~name=Spec.name,
135
+ ~eventTopics,
136
+ ~owner={kind: ComponentType.AutomationSlice, name: Spec.name},
137
+ ~opts,
138
+ )
129
139
 
130
140
  let jsonEventsHandler: EventCollector.jsonEventsHandler = stream =>
131
141
  stream
@@ -56,7 +56,10 @@ function Make(RuntimeEnvironment) {
56
56
  };
57
57
  let memorySize = RuntimeHints$ReventlessInfra.resolveMemory(runtime, 1024);
58
58
  let timeout = RuntimeHints$ReventlessInfra.resolveTimeout(runtime, 30);
59
- let queryDb = SpecificQueryDb.make(Api.api(), Api.apiRole(), undefined, opts);
59
+ let queryDb = SpecificQueryDb.make(Api.api(), Api.apiRole(), undefined, {
60
+ kind: "AutomationSlice",
61
+ name: Spec.name
62
+ }, opts);
60
63
  sourceNames.forEach(sourceName => {
61
64
  if (sourceName in allEventTopics) {
62
65
  return;
@@ -72,7 +75,10 @@ function Make(RuntimeEnvironment) {
72
75
  ]).apply(param => {
73
76
  let publishJsonsFn = param[1];
74
77
  let queryDbOps = param[0];
75
- let ec = SpecificEventCollector.make(Spec.name, eventTopics, opts);
78
+ let ec = SpecificEventCollector.make(Spec.name, eventTopics, {
79
+ kind: "AutomationSlice",
80
+ name: Spec.name
81
+ }, opts);
76
82
  let jsonEventsHandler = stream => Effect.flatMap(Stream.runCollect(stream), jsons => Effect.promise(async () => {
77
83
  Callback.phase1(jsons, context);
78
84
  await syncToQueryDb(queryDbOps);
@@ -56,7 +56,11 @@ module type T = {
56
56
  Runtime.effectHandler<callbackEvent, 'context, unit, string>,
57
57
  >
58
58
 
59
- let make: (~name: string, ~opts: Pulumi.ComponentResource.options=?) => component
59
+ let make: (
60
+ ~name: string,
61
+ ~owner: ResourceAttribution.owner=?,
62
+ ~opts: Pulumi.ComponentResource.options=?,
63
+ ) => component
60
64
  }
61
65
 
62
66
  let toResolvedOutputs = (
@@ -32,6 +32,7 @@ external channel: Component.t<CommandTopic.t, CommandTopic.outputs, 'operations>
32
32
 
33
33
  type channelMaker<'callbackEvent, 'context, 'channelParts, 'runtimeParts> = (
34
34
  ~name: string,
35
+ ~owner: option<ResourceAttribution.owner>,
35
36
  ~opts: Pulumi.ComponentResource.options=?,
36
37
  ) => channel<'callbackEvent, 'context, 'channelParts, 'runtimeParts>
37
38
 
@@ -70,11 +70,11 @@ module Make = (Spec: ReventlessInfra.CommandTopic.T, Channel: CommandTopic_Adapt
70
70
  ->Stream.runCollect
71
71
  ->Effect.map(Array.flat)
72
72
 
73
- let construct = (self, name) => {
73
+ let construct = (~owner=?, self, name) => {
74
74
  let opts = {Pulumi.ComponentResource.parent: self->Component.toPulumiResource}
75
75
  let name = name->ComponentType.name(CommandTopic.componentType)
76
76
 
77
- let channel = Channel.make(~name, ~opts)
77
+ let channel = Channel.make(~name, ~owner, ~opts)
78
78
  self->CommandTopic_Adapter.setChannel(channel)
79
79
 
80
80
  self->Component.setOperations(
@@ -136,11 +136,11 @@ module Make = (Spec: ReventlessInfra.CommandTopic.T, Channel: CommandTopic_Adapt
136
136
  channel.handleChannelEvent(filteringHandler)
137
137
  }
138
138
 
139
- let make = (~name, ~opts=?): component =>
139
+ let make = (~name, ~owner=?, ~opts=?): component =>
140
140
  Component.make(
141
141
  ~componentType=CommandTopic.componentType->ComponentType.toString,
142
142
  ~name,
143
- ~construct,
143
+ ~construct=construct(~owner?, ...),
144
144
  ~opts,
145
145
  )
146
146
  }