@reventlessdev/reventless-aws 3.0.0-alpha.220 → 3.0.0-alpha.222
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/CHANGELOG.md +27 -0
- package/package.json +8 -8
- package/src/Platform.res +2 -2
- package/src/Platform.res.mjs +4 -0
- package/src/Platform_Stack.res +6 -0
- package/src/Platform_Stack.res.mjs +3 -1
- package/src/adapter/AWS_Tags.res +127 -12
- package/src/adapter/AWS_Tags.res.mjs +58 -17
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda.res +13 -1
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda.res.mjs +3 -4
- package/src/adapter/Api/Platform_UIFragments_Lambda.res +13 -1
- package/src/adapter/Api/Platform_UIFragments_Lambda.res.mjs +3 -4
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync.res +12 -0
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync.res.mjs +4 -2
- package/src/adapter/CommandGenerator/InboundTranslationResolvers_AppSync.res +6 -0
- package/src/adapter/CommandGenerator/InboundTranslationResolvers_AppSync.res.mjs +2 -1
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS.res +2 -2
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS.res.mjs +2 -2
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Async.res +2 -2
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Async.res.mjs +2 -2
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_FIFO.res +2 -2
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_FIFO.res.mjs +2 -2
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Sync.res +2 -2
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Sync.res.mjs +2 -2
- package/src/adapter/Counter/CounterHandler_DynamoDbStream.res +1 -0
- package/src/adapter/Counter/CounterHandler_DynamoDbStream.res.mjs +1 -1
- package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb.res +1 -1
- package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb.res.mjs +1 -2
- package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream.res +1 -1
- package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream.res.mjs +1 -1
- package/src/adapter/EventCollector/EventCollectorChannel_SQS.res +2 -2
- package/src/adapter/EventCollector/EventCollectorChannel_SQS.res.mjs +2 -2
- package/src/adapter/EventCollector/EventCollectorChannel_SQS_FIFO.res +2 -2
- package/src/adapter/EventCollector/EventCollectorChannel_SQS_FIFO.res.mjs +2 -2
- package/src/adapter/EventLog/EventLogStorage.res +3 -3
- package/src/adapter/EventLog/EventLogStorage.res.mjs +3 -3
- package/src/adapter/EventLog/EventLogStorage_DynamoDb.res +2 -2
- package/src/adapter/EventLog/EventLogStorage_DynamoDb.res.mjs +2 -2
- package/src/adapter/EventLog/EventLogStorage_DynamoDbStream.res +2 -2
- package/src/adapter/EventLog/EventLogStorage_DynamoDbStream.res.mjs +2 -2
- package/src/adapter/EventLog/EventLogStorage_Postgres.res +1 -1
- package/src/adapter/EventLog/EventLogStorage_Postgres.res.mjs +1 -1
- package/src/adapter/EventLogSubscription/EventLogSubscription_AppSync.res +7 -1
- package/src/adapter/EventLogSubscription/EventLogSubscription_AppSync.res.mjs +2 -2
- package/src/adapter/EventTopic/EventTopicPublisher_DynamoDbStream.res +1 -1
- package/src/adapter/EventTopic/EventTopicPublisher_DynamoDbStream.res.mjs +1 -1
- package/src/adapter/EventTopic/EventTopicPublisher_SNS.res +2 -2
- package/src/adapter/EventTopic/EventTopicPublisher_SNS.res.mjs +2 -2
- package/src/adapter/EventTopic/EventTopicPublisher_SNS_FIFO.res +2 -2
- package/src/adapter/EventTopic/EventTopicPublisher_SNS_FIFO.res.mjs +2 -2
- package/src/adapter/Mcp/MCP_Lambda.res +4 -4
- package/src/adapter/Mcp/MCP_Lambda.res.mjs +1 -1
- package/src/adapter/Postgres/PgChangeFeedRelay_Builder.res +7 -0
- package/src/adapter/Postgres/PgChangeFeedRelay_Builder.res.mjs +4 -2
- package/src/adapter/Postgres/PgMigration_Builder.res +1 -0
- package/src/adapter/Postgres/PgMigration_Builder.res.mjs +1 -1
- package/src/adapter/QueryDb/PgQueryResolver_Builder.res +7 -0
- package/src/adapter/QueryDb/PgQueryResolver_Builder.res.mjs +4 -2
- package/src/adapter/QueryDb/QueryDbStorage.res +6 -6
- package/src/adapter/QueryDb/QueryDbStorage.res.mjs +6 -6
- package/src/adapter/QueryDb/QueryDbStorage_DynamoDb.res +2 -2
- package/src/adapter/QueryDb/QueryDbStorage_DynamoDb.res.mjs +2 -2
- package/src/adapter/QueryDb/QueryDbStorage_DynamoDbStream.res +2 -2
- package/src/adapter/QueryDb/QueryDbStorage_DynamoDbStream.res.mjs +2 -2
- package/src/adapter/QueryDb/QueryDbStorage_Postgres.res +1 -1
- package/src/adapter/QueryDb/QueryDbStorage_Postgres.res.mjs +1 -1
- package/src/adapter/Runtime/AdminEventCollectorEntryPoint.mjs +26 -43
- package/src/adapter/Runtime/AggregateEntryPoint.mjs +52 -45
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res +19 -2
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res.mjs +8 -5
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res +19 -2
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res.mjs +8 -5
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res +9 -1
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res.mjs +4 -2
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate_Async.res +9 -1
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate_Async.res.mjs +4 -2
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res +9 -1
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res.mjs +4 -2
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single_Async.res +9 -1
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single_Async.res.mjs +4 -2
- package/src/adapter/Runtime/AutomationSliceEntryPoint.mjs +36 -22
- package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res +1 -0
- package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res.mjs +1 -1
- package/src/adapter/Runtime/DcbCommandTopicEntryPoint.mjs +39 -42
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_PerEventCollector.res +7 -1
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_PerEventCollector.res.mjs +4 -2
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res +19 -1
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res.mjs +5 -2
- package/src/adapter/Runtime/EventMapperEntryPoint.mjs +25 -23
- package/src/adapter/Runtime/ExtensionPointEntryPoint.mjs +25 -41
- package/src/adapter/Runtime/ExtensionPointRuntime_Builder_PerExtensionPoint.res +1 -0
- package/src/adapter/Runtime/ExtensionPointRuntime_Builder_PerExtensionPoint.res.mjs +1 -1
- package/src/adapter/Runtime/HandlerFactoryHelpers.mjs +126 -0
- package/src/adapter/Runtime/PluginExtensionPointEntryPoint.mjs +24 -41
- package/src/adapter/Runtime/ReadModelEntryPoint.mjs +33 -24
- package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res +52 -2
- package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res.mjs +25 -7
- package/src/adapter/Runtime/SideEffectEntryPoint.mjs +25 -24
- package/src/adapter/Runtime/SideEffectHandlerRuntime_Builder_Single.res +9 -1
- package/src/adapter/Runtime/SideEffectHandlerRuntime_Builder_Single.res.mjs +4 -2
- package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res +1 -0
- package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res.mjs +1 -1
- package/src/adapter/Runtime/StateViewSliceEntryPoint.mjs +26 -21
- package/src/adapter/Runtime/StateViewSliceRuntime_Builder_Single.res +2 -1
- package/src/adapter/Runtime/StateViewSliceRuntime_Builder_Single.res.mjs +2 -2
- package/src/adapter/Runtime/TaskRuntime_Builder_PerBucket.res +1 -0
- package/src/adapter/Runtime/TaskRuntime_Builder_PerBucket.res.mjs +1 -1
- package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents.res +12 -0
- package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents.res.mjs +4 -2
- package/src/adapter/StateTopic/StateTopic_AppSync.res +7 -1
- package/src/adapter/StateTopic/StateTopic_AppSync.res.mjs +2 -2
- package/src/adapter/Task/TaskBucket_S3.res +1 -0
- package/src/adapter/Task/TaskBucket_S3.res.mjs +7 -1
- package/src/components/Aggregate_Builder_Micro.res.mjs +2 -0
- package/src/components/Aggregate_Builder_NoResolver.res.mjs +2 -0
- package/src/components/Aggregate_Builder_PerAggregate.res.mjs +2 -0
- package/src/components/Aggregate_Builder_Single.res.mjs +2 -0
- package/src/components/Aggregate_Builder_Single_Async.res.mjs +2 -0
- package/src/components/Api/AppSync_Adapter.res +12 -0
- package/src/components/Api/AppSync_Adapter.res.mjs +6 -2
- package/src/components/Api/AppSync_MergedApi.res +12 -0
- package/src/components/Api/AppSync_MergedApi.res.mjs +5 -2
- package/src/components/AutomationSlice_Builder.res.mjs +2 -0
- package/src/components/ExtensionPoint_Builder.res.mjs +2 -0
- package/src/components/ForeignReadModel_Builder.res.mjs +4 -0
- package/src/components/OutboundTranslationSlice_Builder.res.mjs +2 -0
- package/src/components/Plugin.res.mjs +2 -0
- package/src/components/ReadModel_Builder_NoResolver.res.mjs +2 -0
- package/src/components/ReadModel_Builder_NoResolver_Stream.res.mjs +2 -0
- package/src/components/ReadModel_Builder_PerReadModel.res.mjs +2 -0
- package/src/components/ReadModel_Builder_Single.res.mjs +2 -0
- package/src/components/ReadModel_Builder_Single_Stream.res.mjs +2 -0
- package/src/components/SideEffectHandler_PerSideEffectHandler.res.mjs +6 -0
- package/src/components/SideEffectHandler_Single.res.mjs +4 -0
- package/src/components/StateViewSlice_Builder.res.mjs +2 -0
- package/src/components/StateViewSlice_Builder_Stream.res.mjs +2 -0
- package/src/components/Task_Builder_PerBucket.res.mjs +4 -0
- package/src/components/Vpc.res +10 -1
- package/src/components/Vpc.res.mjs +3 -1
- package/src/plugin/cloner/ClonerRunner_Fargate.res +26 -1
- package/src/plugin/cloner/ClonerRunner_Fargate.res.mjs +9 -6
- package/src/plugin/heartbeat/HeartbeatRunner_CloudWatchEvents.res +13 -7
- package/src/plugin/heartbeat/HeartbeatRunner_CloudWatchEvents.res.mjs +7 -4
- package/src/plugin/runtime/PluginExtensionPointRuntime_Builder.res +1 -0
- package/src/plugin/runtime/PluginExtensionPointRuntime_Builder.res.mjs +1 -1
- package/src/plugin/runtime/PluginRuntime_Builder.res +3 -1
- package/src/plugin/runtime/PluginRuntime_Builder.res.mjs +2 -2
- package/src/plugin/stack/Plugin_ExtensionPoint_Builder.res.mjs +4 -0
- package/src/plugin/stack/Plugin_Stack.res +26 -1
- package/src/plugin/stack/Plugin_Stack.res.mjs +8 -3
- package/src/util/Util_CognitoGroupUser.res +6 -0
- package/src/util/Util_CognitoGroupUser.res.mjs +3 -1
- package/src/util/Util_DeadLetterQueue.res +8 -2
- package/src/util/Util_DeadLetterQueue.res.mjs +3 -4
- package/src/util/Util_LogAttribution.res +31 -0
- package/src/util/Util_LogAttribution.res.mjs +27 -0
- package/tests/AWS_TagsTest.res +236 -0
- package/tests/AWS_TagsTest.res.mjs +153 -0
- package/tests/HandlerFactoryDispatchTest.res +190 -0
- package/tests/HandlerFactoryDispatchTest.res.mjs +135 -0
- package/tests/integration/AggregateEntryPoint_IntegrationTest.res +5 -3
- package/tests/integration/AggregateEntryPoint_IntegrationTest.res.mjs +5 -3
|
@@ -8,6 +8,7 @@ import * as Aggregate$ReventlessCore from "@reventlessdev/reventless-core/src/co
|
|
|
8
8
|
import * as Component$ReventlessCore from "@reventlessdev/reventless-core/src/components/Component.res.mjs";
|
|
9
9
|
import * as Util_Bundle$ReventlessAws from "../../util/Util_Bundle.res.mjs";
|
|
10
10
|
import * as ComponentType$ReventlessCore from "@reventlessdev/reventless-core/src/ComponentType.res.mjs";
|
|
11
|
+
import * as Util_LogAttribution$ReventlessAws from "../../util/Util_LogAttribution.res.mjs";
|
|
11
12
|
import * as RuntimeEnvironment_Lambda$ReventlessAws from "./RuntimeEnvironment_Lambda.res.mjs";
|
|
12
13
|
import * as EventCollectorChannel_DynamoDbStream$ReventlessAws from "../EventCollector/EventCollectorChannel_DynamoDbStream.res.mjs";
|
|
13
14
|
|
|
@@ -139,11 +140,12 @@ function finish() {
|
|
|
139
140
|
let lambdaName = name + "CmdHandler";
|
|
140
141
|
let specModule = Stdlib_Option.getOr(JSON.stringify(info.specModulePath), `""`);
|
|
141
142
|
let behaviorModule = Stdlib_Option.getOr(JSON.stringify(info.behaviorModulePath), `""`);
|
|
143
|
+
let pluginFragment = Util_LogAttribution$ReventlessAws.pluginFragment(`AggregateRuntime(` + spec.aggregateName + `)`);
|
|
142
144
|
let handlerConfigOutput = Pulumi.all([
|
|
143
145
|
info.eventLogTableName,
|
|
144
146
|
spec.queueUrl,
|
|
145
147
|
spec.queueArn
|
|
146
|
-
]).apply(param => `{"handlers":[{"specModule":` + specModule + `,"behaviorModule":` + behaviorModule + `,"eventLogTable":"` + param[0] + `","queueUrl":"` + param[1] + `","queueArn":"` + param[2] + `"}]}`);
|
|
148
|
+
]).apply(param => `{"handlers":[{"specModule":` + specModule + `,"behaviorModule":` + behaviorModule + `,"eventLogTable":"` + param[0] + `","queueUrl":"` + param[1] + `","queueArn":"` + param[2] + `"` + pluginFragment + `}]}`);
|
|
147
149
|
let envVars = {};
|
|
148
150
|
envVars["HANDLER_CONFIG"] = handlerConfigOutput;
|
|
149
151
|
let packageDirs = {};
|
|
@@ -152,7 +154,7 @@ function finish() {
|
|
|
152
154
|
packageDirs[specPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(specPkg);
|
|
153
155
|
packageDirs[behaviorPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(behaviorPkg);
|
|
154
156
|
let match = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/AggregateEntryPoint.mjs", packageDirs, undefined);
|
|
155
|
-
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(lambdaName, "CommandHandler", match.code, match.sourceCodeHash, envVars, spec.memorySize, spec.timeout, undefined, undefined, undefined, undefined, undefined, aggregateOpts);
|
|
157
|
+
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(lambdaName, "CommandHandler", "Aggregate", match.code, match.sourceCodeHash, envVars, spec.memorySize, spec.timeout, undefined, undefined, undefined, undefined, undefined, aggregateOpts);
|
|
156
158
|
spec.connects.forEach(connect => connect(runtime));
|
|
157
159
|
let channelSpecs = Stdlib_Option.mapOr(spec.eventCollectorChannelSpec, [], cs => [cs]);
|
|
158
160
|
EventCollectorChannel_DynamoDbStream$ReventlessAws.connect(name, channelSpecs, runtime, aggregateOpts);
|
|
@@ -191,10 +191,17 @@ let finish = () =>
|
|
|
191
191
|
let behaviorModule =
|
|
192
192
|
info.behaviorModulePath->JSON.stringifyAny->Option.getOr(`""`)
|
|
193
193
|
|
|
194
|
+
// `plugin` cannot be resolved inside the Lambda — LogPrefix's registry is a
|
|
195
|
+
// deploy-time structure, and the Lambda-name fallback yields nothing for a
|
|
196
|
+
// shared or per-aggregate command handler. Resolve it here; the shell still
|
|
197
|
+
// derives `comp` itself from the spec name.
|
|
198
|
+
let pluginFragment = Util_LogAttribution.pluginFragment(
|
|
199
|
+
~comp=`AggregateRuntime(${spec.aggregateName})`,
|
|
200
|
+
)
|
|
194
201
|
let handlerConfigOutput =
|
|
195
202
|
Pulumi.Output.all3((info.eventLogTableName, spec.queueUrl, spec.queueArn))
|
|
196
203
|
->Pulumi.Output.apply(((table, queueUrl, queueArn)) =>
|
|
197
|
-
`{"handlers":[{"specModule":${specModule},"behaviorModule":${behaviorModule},"eventLogTable":"${table}","queueUrl":"${queueUrl}","queueArn":"${queueArn}"}]}`
|
|
204
|
+
`{"handlers":[{"specModule":${specModule},"behaviorModule":${behaviorModule},"eventLogTable":"${table}","queueUrl":"${queueUrl}","queueArn":"${queueArn}"${pluginFragment}}]}`
|
|
198
205
|
)
|
|
199
206
|
|
|
200
207
|
let envVars: dict<Pulumi.Input.t<string>> = Dict.make()
|
|
@@ -215,6 +222,7 @@ let finish = () =>
|
|
|
215
222
|
let runtime = RuntimeEnvironment_Lambda.makeFromCodeAsset(
|
|
216
223
|
~name,
|
|
217
224
|
~unitKind=ReventlessCore.Monitoring.CommandHandler,
|
|
225
|
+
~componentKind=ReventlessCore.ComponentType.Aggregate,
|
|
218
226
|
~code,
|
|
219
227
|
~sourceCodeHash,
|
|
220
228
|
~envVars,
|
|
@@ -8,6 +8,7 @@ import * as Aggregate$ReventlessCore from "@reventlessdev/reventless-core/src/co
|
|
|
8
8
|
import * as Component$ReventlessCore from "@reventlessdev/reventless-core/src/components/Component.res.mjs";
|
|
9
9
|
import * as Util_Bundle$ReventlessAws from "../../util/Util_Bundle.res.mjs";
|
|
10
10
|
import * as ComponentType$ReventlessCore from "@reventlessdev/reventless-core/src/ComponentType.res.mjs";
|
|
11
|
+
import * as Util_LogAttribution$ReventlessAws from "../../util/Util_LogAttribution.res.mjs";
|
|
11
12
|
import * as RuntimeEnvironment_Lambda$ReventlessAws from "./RuntimeEnvironment_Lambda.res.mjs";
|
|
12
13
|
import * as EventCollectorChannel_DynamoDbStream$ReventlessAws from "../EventCollector/EventCollectorChannel_DynamoDbStream.res.mjs";
|
|
13
14
|
|
|
@@ -138,11 +139,12 @@ function finish() {
|
|
|
138
139
|
let name = ComponentType$ReventlessCore.name(spec.aggregateName, Aggregate$ReventlessCore.componentType);
|
|
139
140
|
let specModule = Stdlib_Option.getOr(JSON.stringify(info.specModulePath), `""`);
|
|
140
141
|
let behaviorModule = Stdlib_Option.getOr(JSON.stringify(info.behaviorModulePath), `""`);
|
|
142
|
+
let pluginFragment = Util_LogAttribution$ReventlessAws.pluginFragment(`AggregateRuntime(` + spec.aggregateName + `)`);
|
|
141
143
|
let handlerConfigOutput = Pulumi.all([
|
|
142
144
|
info.eventLogTableName,
|
|
143
145
|
spec.queueUrl,
|
|
144
146
|
spec.queueArn
|
|
145
|
-
]).apply(param => `{"handlers":[{"specModule":` + specModule + `,"behaviorModule":` + behaviorModule + `,"eventLogTable":"` + param[0] + `","queueUrl":"` + param[1] + `","queueArn":"` + param[2] + `"}]}`);
|
|
147
|
+
]).apply(param => `{"handlers":[{"specModule":` + specModule + `,"behaviorModule":` + behaviorModule + `,"eventLogTable":"` + param[0] + `","queueUrl":"` + param[1] + `","queueArn":"` + param[2] + `"` + pluginFragment + `}]}`);
|
|
146
148
|
let envVars = {};
|
|
147
149
|
envVars["HANDLER_CONFIG"] = handlerConfigOutput;
|
|
148
150
|
envVars["DISPATCH_MODE"] = "async";
|
|
@@ -152,7 +154,7 @@ function finish() {
|
|
|
152
154
|
packageDirs[specPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(specPkg);
|
|
153
155
|
packageDirs[behaviorPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(behaviorPkg);
|
|
154
156
|
let match = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/AggregateEntryPoint.mjs", packageDirs, undefined);
|
|
155
|
-
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(name, "CommandHandler", match.code, match.sourceCodeHash, envVars, spec.memorySize, spec.timeout, undefined, undefined, undefined, undefined, undefined, aggregateOpts);
|
|
157
|
+
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(name, "CommandHandler", "Aggregate", match.code, match.sourceCodeHash, envVars, spec.memorySize, spec.timeout, undefined, undefined, undefined, undefined, undefined, aggregateOpts);
|
|
156
158
|
spec.connects.forEach(connect => connect(runtime));
|
|
157
159
|
let channelSpecs = Stdlib_Option.mapOr(spec.eventCollectorChannelSpec, [], cs => [cs]);
|
|
158
160
|
EventCollectorChannel_DynamoDbStream$ReventlessAws.connect(name, channelSpecs, runtime, aggregateOpts);
|
|
@@ -250,6 +250,13 @@ let finish = () =>
|
|
|
250
250
|
let behaviorModule =
|
|
251
251
|
info.behaviorModulePath->JSON.stringifyAny->Option.getOr(`""`)
|
|
252
252
|
|
|
253
|
+
// `plugin` cannot be resolved inside the Lambda — LogPrefix's registry is a
|
|
254
|
+
// deploy-time structure, and the Lambda-name fallback yields nothing for a
|
|
255
|
+
// shared or per-aggregate command handler. Resolve it here; the shell still
|
|
256
|
+
// derives `comp` itself from the spec name.
|
|
257
|
+
let pluginFragment = Util_LogAttribution.pluginFragment(
|
|
258
|
+
~comp=`AggregateRuntime(${spec.aggregateName})`,
|
|
259
|
+
)
|
|
253
260
|
let handlerJson =
|
|
254
261
|
Pulumi.Output.all4((
|
|
255
262
|
info.eventLogTableName,
|
|
@@ -258,7 +265,7 @@ let finish = () =>
|
|
|
258
265
|
pgConnectionFragment,
|
|
259
266
|
))
|
|
260
267
|
->Pulumi.Output.apply(((table, queueUrl, queueArn, pgFragment)) =>
|
|
261
|
-
`{"specModule":${specModule},"behaviorModule":${behaviorModule},"eventLogTable":"${table}","queueUrl":"${queueUrl}","queueArn":"${queueArn}"${pgFragment}}`
|
|
268
|
+
`{"specModule":${specModule},"behaviorModule":${behaviorModule},"eventLogTable":"${table}","queueUrl":"${queueUrl}","queueArn":"${queueArn}"${pluginFragment}${pgFragment}}`
|
|
262
269
|
)
|
|
263
270
|
let _ = handlerOutputs->Array.push(handlerJson)
|
|
264
271
|
| None =>
|
|
@@ -327,6 +334,7 @@ let finish = () =>
|
|
|
327
334
|
let runtime = RuntimeEnvironment_Lambda.makeFromCodeAsset(
|
|
328
335
|
~name="AllAggregatesCmdHandler",
|
|
329
336
|
~unitKind=ReventlessCore.Monitoring.CommandHandler,
|
|
337
|
+
~componentKind=ReventlessCore.ComponentType.Aggregate,
|
|
330
338
|
~code,
|
|
331
339
|
~sourceCodeHash,
|
|
332
340
|
~envVars,
|
|
@@ -13,6 +13,7 @@ import * as PolicyDocument$PulumiAws from "@reventlessdev/rescript-pulumi-aws/sr
|
|
|
13
13
|
import * as Util_Bundle$ReventlessAws from "../../util/Util_Bundle.res.mjs";
|
|
14
14
|
import * as PgConnection$ReventlessAws from "../Postgres/PgConnection.res.mjs";
|
|
15
15
|
import * as EventLogBackend$ReventlessAws from "../EventLog/EventLogBackend.res.mjs";
|
|
16
|
+
import * as Util_LogAttribution$ReventlessAws from "../../util/Util_LogAttribution.res.mjs";
|
|
16
17
|
import * as RuntimeEnvironment_Lambda$ReventlessAws from "./RuntimeEnvironment_Lambda.res.mjs";
|
|
17
18
|
import * as CommandTopicChannel_SQS_Sync$ReventlessAws from "../CommandTopic/CommandTopicChannel_SQS_Sync.res.mjs";
|
|
18
19
|
import * as EventCollectorChannel_DynamoDbStream$ReventlessAws from "../EventCollector/EventCollectorChannel_DynamoDbStream.res.mjs";
|
|
@@ -174,12 +175,13 @@ function finish() {
|
|
|
174
175
|
packageDirs[behaviorPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(behaviorPkg);
|
|
175
176
|
let specModule = Stdlib_Option.getOr(JSON.stringify(info.specModulePath), `""`);
|
|
176
177
|
let behaviorModule = Stdlib_Option.getOr(JSON.stringify(info.behaviorModulePath), `""`);
|
|
178
|
+
let pluginFragment = Util_LogAttribution$ReventlessAws.pluginFragment(`AggregateRuntime(` + spec.aggregateName + `)`);
|
|
177
179
|
let handlerJson = Pulumi.all([
|
|
178
180
|
info.eventLogTableName,
|
|
179
181
|
spec.queueUrl,
|
|
180
182
|
spec.queueArn,
|
|
181
183
|
pgConnectionFragment
|
|
182
|
-
]).apply(param => `{"specModule":` + specModule + `,"behaviorModule":` + behaviorModule + `,"eventLogTable":"` + param[0] + `","queueUrl":"` + param[1] + `","queueArn":"` + param[2] + `"` + param[3] + `}`);
|
|
184
|
+
]).apply(param => `{"specModule":` + specModule + `,"behaviorModule":` + behaviorModule + `,"eventLogTable":"` + param[0] + `","queueUrl":"` + param[1] + `","queueArn":"` + param[2] + `"` + pluginFragment + param[3] + `}`);
|
|
183
185
|
handlerOutputs.push(handlerJson);
|
|
184
186
|
});
|
|
185
187
|
let handlerConfigOutput = Pulumi.all(handlerOutputs).apply(handlers => `{"handlers":[` + handlers.join(",") + `]}`);
|
|
@@ -201,7 +203,7 @@ function finish() {
|
|
|
201
203
|
subnetIds: pgSelection.subnetIds,
|
|
202
204
|
securityGroupIds: [sgId]
|
|
203
205
|
})) : undefined;
|
|
204
|
-
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset("AllAggregatesCmdHandler", "CommandHandler", match.code, match.sourceCodeHash, envVars, memorySize, timeout, cfg.reservedConcurrency, cfg.ephemeralStorageMb, cfg.logRetentionDays, undefined, vpcConfig, opts);
|
|
206
|
+
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset("AllAggregatesCmdHandler", "CommandHandler", "Aggregate", match.code, match.sourceCodeHash, envVars, memorySize, timeout, cfg.reservedConcurrency, cfg.ephemeralStorageMb, cfg.logRetentionDays, undefined, vpcConfig, opts);
|
|
205
207
|
if (pgSelection !== undefined) {
|
|
206
208
|
pgSelection.connectionConfig.apply(cc => new (Aws.iam.RolePolicy)("AllAggregatesCmdHandler-pgSecret", {
|
|
207
209
|
policy: PolicyDocument$PulumiAws.toJsonString(PolicyDocument$PulumiAws.make(undefined, "AllAggregatesCmdHandler-pgSecretPolicy", [{
|
|
@@ -231,6 +231,13 @@ let finish = () =>
|
|
|
231
231
|
let behaviorModule =
|
|
232
232
|
info.behaviorModulePath->JSON.stringifyAny->Option.getOr(`""`)
|
|
233
233
|
|
|
234
|
+
// `plugin` cannot be resolved inside the Lambda — LogPrefix's registry is a
|
|
235
|
+
// deploy-time structure, and the Lambda-name fallback yields nothing for a
|
|
236
|
+
// shared or per-aggregate command handler. Resolve it here; the shell still
|
|
237
|
+
// derives `comp` itself from the spec name.
|
|
238
|
+
let pluginFragment = Util_LogAttribution.pluginFragment(
|
|
239
|
+
~comp=`AggregateRuntime(${spec.aggregateName})`,
|
|
240
|
+
)
|
|
234
241
|
let handlerJson =
|
|
235
242
|
Pulumi.Output.all4((
|
|
236
243
|
info.eventLogTableName,
|
|
@@ -239,7 +246,7 @@ let finish = () =>
|
|
|
239
246
|
pgConnectionFragment,
|
|
240
247
|
))
|
|
241
248
|
->Pulumi.Output.apply(((table, queueUrl, queueArn, pgFragment)) =>
|
|
242
|
-
`{"specModule":${specModule},"behaviorModule":${behaviorModule},"eventLogTable":"${table}","queueUrl":"${queueUrl}","queueArn":"${queueArn}"${pgFragment}}`
|
|
249
|
+
`{"specModule":${specModule},"behaviorModule":${behaviorModule},"eventLogTable":"${table}","queueUrl":"${queueUrl}","queueArn":"${queueArn}"${pluginFragment}${pgFragment}}`
|
|
243
250
|
)
|
|
244
251
|
let _ = handlerOutputs->Array.push(handlerJson)
|
|
245
252
|
| None =>
|
|
@@ -302,6 +309,7 @@ let finish = () =>
|
|
|
302
309
|
let runtime = RuntimeEnvironment_Lambda.makeFromCodeAsset(
|
|
303
310
|
~name="AllAggregatesAsyncCmdHandler",
|
|
304
311
|
~unitKind=ReventlessCore.Monitoring.CommandHandler,
|
|
312
|
+
~componentKind=ReventlessCore.ComponentType.Aggregate,
|
|
305
313
|
~code,
|
|
306
314
|
~sourceCodeHash,
|
|
307
315
|
~envVars,
|
|
@@ -13,6 +13,7 @@ import * as PolicyDocument$PulumiAws from "@reventlessdev/rescript-pulumi-aws/sr
|
|
|
13
13
|
import * as Util_Bundle$ReventlessAws from "../../util/Util_Bundle.res.mjs";
|
|
14
14
|
import * as PgConnection$ReventlessAws from "../Postgres/PgConnection.res.mjs";
|
|
15
15
|
import * as EventLogBackend$ReventlessAws from "../EventLog/EventLogBackend.res.mjs";
|
|
16
|
+
import * as Util_LogAttribution$ReventlessAws from "../../util/Util_LogAttribution.res.mjs";
|
|
16
17
|
import * as RuntimeEnvironment_Lambda$ReventlessAws from "./RuntimeEnvironment_Lambda.res.mjs";
|
|
17
18
|
import * as CommandTopicChannel_SQS_Async$ReventlessAws from "../CommandTopic/CommandTopicChannel_SQS_Async.res.mjs";
|
|
18
19
|
import * as EventCollectorChannel_DynamoDbStream$ReventlessAws from "../EventCollector/EventCollectorChannel_DynamoDbStream.res.mjs";
|
|
@@ -166,12 +167,13 @@ function finish() {
|
|
|
166
167
|
packageDirs[behaviorPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(behaviorPkg);
|
|
167
168
|
let specModule = Stdlib_Option.getOr(JSON.stringify(info.specModulePath), `""`);
|
|
168
169
|
let behaviorModule = Stdlib_Option.getOr(JSON.stringify(info.behaviorModulePath), `""`);
|
|
170
|
+
let pluginFragment = Util_LogAttribution$ReventlessAws.pluginFragment(`AggregateRuntime(` + spec.aggregateName + `)`);
|
|
169
171
|
let handlerJson = Pulumi.all([
|
|
170
172
|
info.eventLogTableName,
|
|
171
173
|
spec.queueUrl,
|
|
172
174
|
spec.queueArn,
|
|
173
175
|
pgConnectionFragment
|
|
174
|
-
]).apply(param => `{"specModule":` + specModule + `,"behaviorModule":` + behaviorModule + `,"eventLogTable":"` + param[0] + `","queueUrl":"` + param[1] + `","queueArn":"` + param[2] + `"` + param[3] + `}`);
|
|
176
|
+
]).apply(param => `{"specModule":` + specModule + `,"behaviorModule":` + behaviorModule + `,"eventLogTable":"` + param[0] + `","queueUrl":"` + param[1] + `","queueArn":"` + param[2] + `"` + pluginFragment + param[3] + `}`);
|
|
175
177
|
handlerOutputs.push(handlerJson);
|
|
176
178
|
});
|
|
177
179
|
let handlerConfigOutput = Pulumi.all(handlerOutputs).apply(handlers => `{"handlers":[` + handlers.join(",") + `]}`);
|
|
@@ -190,7 +192,7 @@ function finish() {
|
|
|
190
192
|
subnetIds: pgSelection.subnetIds,
|
|
191
193
|
securityGroupIds: [sgId]
|
|
192
194
|
})) : undefined;
|
|
193
|
-
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset("AllAggregatesAsyncCmdHandler", "CommandHandler", match.code, match.sourceCodeHash, envVars, memorySize, timeout, cfg.reservedConcurrency, cfg.ephemeralStorageMb, cfg.logRetentionDays, undefined, vpcConfig, opts);
|
|
195
|
+
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset("AllAggregatesAsyncCmdHandler", "CommandHandler", "Aggregate", match.code, match.sourceCodeHash, envVars, memorySize, timeout, cfg.reservedConcurrency, cfg.ephemeralStorageMb, cfg.logRetentionDays, undefined, vpcConfig, opts);
|
|
194
196
|
if (pgSelection !== undefined) {
|
|
195
197
|
pgSelection.connectionConfig.apply(cc => new (Aws.iam.RolePolicy)("AllAggregatesAsyncCmdHandler-pgSecret", {
|
|
196
198
|
policy: PolicyDocument$PulumiAws.toJsonString(PolicyDocument$PulumiAws.make(undefined, "AllAggregatesAsyncCmdHandler-pgSecretPolicy", [{
|
|
@@ -7,8 +7,16 @@ import * as Effect from "effect/Effect";
|
|
|
7
7
|
import * as Stream from "effect/Stream";
|
|
8
8
|
import * as Chunk from "effect/Chunk";
|
|
9
9
|
import { parseJsonOrThrow } from "sury/src/S.res.mjs";
|
|
10
|
-
import {
|
|
11
|
-
|
|
10
|
+
import {
|
|
11
|
+
makeTableRef,
|
|
12
|
+
makeQueueRef,
|
|
13
|
+
log,
|
|
14
|
+
runEffect,
|
|
15
|
+
setRequestId,
|
|
16
|
+
extractMetaField,
|
|
17
|
+
extractSentTimestamp,
|
|
18
|
+
extractRetryCount,
|
|
19
|
+
} from "./HandlerFactoryHelpers.mjs";
|
|
12
20
|
import { save as qdbSave } from "@reventlessdev/reventless-aws/src/adapter/QueryDb/QueryDbStorage_DynamoDb_Runtime.res.mjs";
|
|
13
21
|
import { publishJsons as sqsPublishJsons } from "@reventlessdev/reventless-aws/src/adapter/CommandTopic/CommandTopicChannel_SQS_Runtime.res.mjs";
|
|
14
22
|
import { Make as automationSliceCallbackMake } from "@reventlessdev/reventless-core/src/components/AutomationSlice/AutomationSlice_Callback.res.mjs";
|
|
@@ -17,21 +25,13 @@ import { Make as outboundTranslationSliceCallbackMake } from "@reventlessdev/rev
|
|
|
17
25
|
|
|
18
26
|
const dynamicImport = (specifier) => import('/var/task/node_modules/' + specifier);
|
|
19
27
|
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
// no-op if the unified logger isn't installed.
|
|
28
|
-
.pipe(Effect.annotateLogs("correlationId", correlationId || "unknown"))
|
|
29
|
-
.pipe(Effect.annotateLogs("requestId", _currentRequestId));
|
|
30
|
-
if (pluginName) e = e.pipe(Effect.annotateLogs("plugin", pluginName));
|
|
31
|
-
return e
|
|
32
|
-
.pipe(Effect.provideService(requestContextTag, { correlationId: correlationId || "unknown" }))
|
|
33
|
-
.pipe(Effect.runPromise);
|
|
34
|
-
}
|
|
28
|
+
// Same comp the slice's own callback logs under (AutomationSlice_Callback /
|
|
29
|
+
// OutboundTranslationSlice_Callback), so a filter catches both the framework's
|
|
30
|
+
// lines and the application handler's.
|
|
31
|
+
const sliceComp = (callbackType, sliceName) =>
|
|
32
|
+
callbackType === "outbound"
|
|
33
|
+
? `OutboundTranslationSlice(${sliceName})`
|
|
34
|
+
: `AutomationSlice(${sliceName})`;
|
|
35
35
|
|
|
36
36
|
function groupBySource(records) {
|
|
37
37
|
const dict = {};
|
|
@@ -95,8 +95,12 @@ async function buildAllHandlers() {
|
|
|
95
95
|
// Multiple slices can share one source stream (e.g. several automation
|
|
96
96
|
// slices reacting to the same DcbEventLog). Accumulate all handlers per
|
|
97
97
|
// source ARN; a plain assignment collapses them to one (Promise.all race),
|
|
98
|
-
// silently dropping the rest.
|
|
99
|
-
|
|
98
|
+
// silently dropping the rest. Each keeps its own comp — that is what
|
|
99
|
+
// separates co-hosted slices in the log stream.
|
|
100
|
+
(handlers[h.sourceUrn] ||= []).push({
|
|
101
|
+
handler,
|
|
102
|
+
comp: sliceComp(h.callbackType, specModule.name),
|
|
103
|
+
});
|
|
100
104
|
}));
|
|
101
105
|
return handlers;
|
|
102
106
|
}
|
|
@@ -104,7 +108,7 @@ async function buildAllHandlers() {
|
|
|
104
108
|
const initPromise = buildAllHandlers();
|
|
105
109
|
|
|
106
110
|
export async function handler(event, context) {
|
|
107
|
-
|
|
111
|
+
setRequestId(context?.awsRequestId);
|
|
108
112
|
const handlers = await initPromise;
|
|
109
113
|
const records = event.Records || [];
|
|
110
114
|
const grouped = groupBySource(records);
|
|
@@ -113,8 +117,18 @@ export async function handler(event, context) {
|
|
|
113
117
|
const streamHandlers = handlers[arn];
|
|
114
118
|
if (streamHandlers !== undefined && streamHandlers.length > 0) {
|
|
115
119
|
log.debug("found " + streamHandlers.length + " handler(s) for " + arn, { comp: "AutomationSliceRuntime" });
|
|
116
|
-
|
|
117
|
-
|
|
120
|
+
const correlationId = extractMetaField(subRecords, "correlationId");
|
|
121
|
+
const causationId = extractMetaField(subRecords, "causationId");
|
|
122
|
+
const timestamp = extractSentTimestamp(subRecords);
|
|
123
|
+
const retryCount = extractRetryCount(subRecords);
|
|
124
|
+
await Promise.all(streamHandlers.map(({ handler: h, comp }) =>
|
|
125
|
+
runEffect(h({ Records: subRecords }, context), {
|
|
126
|
+
correlationId,
|
|
127
|
+
causationId,
|
|
128
|
+
comp,
|
|
129
|
+
timestamp,
|
|
130
|
+
retryCount,
|
|
131
|
+
})
|
|
118
132
|
));
|
|
119
133
|
} else {
|
|
120
134
|
log.warn("no handler found: " + arn, { comp: "AutomationSliceRuntime" });
|
|
@@ -166,6 +166,7 @@ let finish = () =>
|
|
|
166
166
|
let runtime = RuntimeEnvironment_Lambda.makeFromCodeAsset(
|
|
167
167
|
~name="AllAutomationSlices",
|
|
168
168
|
~unitKind=ReventlessCore.Monitoring.Reactor,
|
|
169
|
+
~componentKind=ReventlessCore.ComponentType.AutomationSlice,
|
|
169
170
|
~code,
|
|
170
171
|
~sourceCodeHash,
|
|
171
172
|
~envVars,
|
|
@@ -120,7 +120,7 @@ function finish() {
|
|
|
120
120
|
let envVars = {};
|
|
121
121
|
envVars["HANDLER_CONFIG"] = handlerConfigOutput;
|
|
122
122
|
let match$1 = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/AutomationSliceEntryPoint.mjs", packageDirs, undefined);
|
|
123
|
-
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset("AllAutomationSlices", "Reactor", match$1.code, match$1.sourceCodeHash, envVars, match[0], match[1], undefined, undefined, undefined, undefined, undefined, opts);
|
|
123
|
+
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset("AllAutomationSlices", "Reactor", "AutomationSlice", match$1.code, match$1.sourceCodeHash, envVars, match[0], match[1], undefined, undefined, undefined, undefined, undefined, opts);
|
|
124
124
|
let channelSpecs = storedSpecs.map(param => param.channelSpec);
|
|
125
125
|
EventCollectorChannel_DynamoDbStream$ReventlessAws.connect("AllAutomationSlices", channelSpecs, runtime, opts);
|
|
126
126
|
} else {
|
|
@@ -6,8 +6,16 @@
|
|
|
6
6
|
import * as Chunk from "effect/Chunk";
|
|
7
7
|
import * as Effect from "effect/Effect";
|
|
8
8
|
import * as Stream from "effect/Stream";
|
|
9
|
-
import {
|
|
10
|
-
|
|
9
|
+
import {
|
|
10
|
+
patchSpecId,
|
|
11
|
+
makeQueueRef,
|
|
12
|
+
log,
|
|
13
|
+
runEffect,
|
|
14
|
+
setRequestId,
|
|
15
|
+
extractMetaField,
|
|
16
|
+
extractSentTimestamp,
|
|
17
|
+
extractRetryCount,
|
|
18
|
+
} from "./HandlerFactoryHelpers.mjs";
|
|
11
19
|
import { Make as dcbEventLogOperationsMake } from "@reventlessdev/reventless-core/src/components/DcbEventLog/DcbEventLog_Operations.res.mjs";
|
|
12
20
|
import { makeCommandGenerator } from "./CommandGeneratorEntryPoint_Ops.res.mjs";
|
|
13
21
|
import { commandOutcomeToJson, runInlineAndCollect } from "@reventlessdev/reventless-core/src/components/CommandTopic/CommandTopic_Helpers.res.mjs";
|
|
@@ -39,39 +47,12 @@ function extractTypeName(json) {
|
|
|
39
47
|
return undefined;
|
|
40
48
|
}
|
|
41
49
|
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
// decoded by EffectLogger.install() from Effect log annotations. Harmless
|
|
49
|
-
// no-op if the unified logger isn't installed.
|
|
50
|
-
.pipe(Effect.annotateLogs("correlationId", correlationId || "unknown"))
|
|
51
|
-
.pipe(Effect.annotateLogs("requestId", _currentRequestId));
|
|
52
|
-
if (pluginName) e = e.pipe(Effect.annotateLogs("plugin", pluginName));
|
|
53
|
-
return e
|
|
54
|
-
.pipe(Effect.provideService(requestContextTag, { correlationId: correlationId || "unknown" }))
|
|
55
|
-
.pipe(Effect.runPromise);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function extractCorrelationId(records) {
|
|
59
|
-
const first = records[0];
|
|
60
|
-
if (!first) return undefined;
|
|
61
|
-
const body = first.body;
|
|
62
|
-
if (body == null) return undefined;
|
|
63
|
-
try {
|
|
64
|
-
const parsed = JSON.parse(body);
|
|
65
|
-
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
66
|
-
const meta = parsed.meta;
|
|
67
|
-
if (meta && typeof meta === "object" && !Array.isArray(meta)) {
|
|
68
|
-
const cid = meta.correlationId;
|
|
69
|
-
if (typeof cid === "string") return cid;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
} catch (_) {}
|
|
73
|
-
return undefined;
|
|
74
|
-
}
|
|
50
|
+
// This Lambda hosts one plugin's StateChangeSlices behind a composite handler
|
|
51
|
+
// that routes per command TAG *inside* the stream — so the dispatch boundary
|
|
52
|
+
// names the runtime group, not the individual slice. `Kind(Name)` matches the
|
|
53
|
+
// shape every other comp uses, and the plugin name resolves through
|
|
54
|
+
// LogPrefix.
|
|
55
|
+
const dcbComp = (plugin) => `DcbCommandTopicRuntime(${plugin})`;
|
|
75
56
|
|
|
76
57
|
// Exported for tests: build the [sqsHandler, cmdGenHandler] pair from an
|
|
77
58
|
// already-parsed `HANDLER_CONFIG` shape, with an injectable module loader.
|
|
@@ -204,7 +185,10 @@ export async function buildHandlersForConfig(config, opts = {}) {
|
|
|
204
185
|
return generateCommand({ ...event, meta, identity });
|
|
205
186
|
};
|
|
206
187
|
|
|
207
|
-
|
|
188
|
+
// Third element is additive — existing callers (the integration tests) keep
|
|
189
|
+
// destructuring the first two. No deploy-time `plugin` fragment needed here:
|
|
190
|
+
// this Lambda serves exactly one plugin and HANDLER_CONFIG already names it.
|
|
191
|
+
return [sqsHandler, cmdGenHandler, dcbComp(config.pluginName), config.pluginName];
|
|
208
192
|
}
|
|
209
193
|
|
|
210
194
|
async function buildHandler() {
|
|
@@ -212,7 +196,7 @@ async function buildHandler() {
|
|
|
212
196
|
// Importing this module without HANDLER_CONFIG (e.g. from a test that drives
|
|
213
197
|
// `buildHandlersForConfig` directly) must not crash module evaluation.
|
|
214
198
|
// Lambda always sets HANDLER_CONFIG; the production path is unchanged.
|
|
215
|
-
if (!configStr) return [null, null];
|
|
199
|
+
if (!configStr) return [null, null, undefined, undefined];
|
|
216
200
|
const config = JSON.parse(configStr);
|
|
217
201
|
return buildHandlersForConfig(config, { loadModule: dynamicImport });
|
|
218
202
|
}
|
|
@@ -220,21 +204,34 @@ async function buildHandler() {
|
|
|
220
204
|
const initPromise = buildHandler();
|
|
221
205
|
|
|
222
206
|
export async function handler(event, context) {
|
|
223
|
-
|
|
224
|
-
const [sqsHandler, cmdGenHandler] = await initPromise;
|
|
207
|
+
setRequestId(context?.awsRequestId);
|
|
208
|
+
const [sqsHandler, cmdGenHandler, comp, plugin] = await initPromise;
|
|
225
209
|
|
|
226
210
|
// Route 1: AppSync direct invocation — payload carries the CommandGenerator.payload
|
|
227
211
|
// shape (`{command, arguments, meta, identity?}`).
|
|
228
212
|
if (event.command != null && event.arguments != null) {
|
|
229
213
|
log.debug("AppSync direct invocation (" + DISPATCH_MODE + ")", { comp: "DcbCommandTopicRuntime" });
|
|
230
|
-
|
|
214
|
+
// Direct invoke: the envelope is on `event.meta`, and there is no send time
|
|
215
|
+
// or receive count on this path.
|
|
216
|
+
const outcome = await runEffect(cmdGenHandler(event), {
|
|
217
|
+
correlationId: event.meta?.correlationId,
|
|
218
|
+
causationId: event.meta?.causationId,
|
|
219
|
+
comp,
|
|
220
|
+
plugin,
|
|
221
|
+
});
|
|
231
222
|
return commandOutcomeToJson(outcome);
|
|
232
223
|
}
|
|
233
224
|
|
|
234
225
|
// Route 2: SQS CommandTopic events
|
|
235
226
|
const records = event.Records || [];
|
|
236
|
-
const correlationId = extractCorrelationId(records);
|
|
237
227
|
log.debug("processing " + records.length.toString() + " record(s)", { comp: "DcbCommandTopicRuntime" });
|
|
238
|
-
await runEffect(
|
|
228
|
+
await runEffect(sqsHandler(event, context), {
|
|
229
|
+
correlationId: extractMetaField(records, "correlationId"),
|
|
230
|
+
causationId: extractMetaField(records, "causationId"),
|
|
231
|
+
comp,
|
|
232
|
+
plugin,
|
|
233
|
+
timestamp: extractSentTimestamp(records),
|
|
234
|
+
retryCount: extractRetryCount(records),
|
|
235
|
+
});
|
|
239
236
|
return "";
|
|
240
237
|
}
|
|
@@ -67,11 +67,16 @@ let forEventCollector: ReventlessCore.Runtime.forEventCollector<
|
|
|
67
67
|
let mappingsModule =
|
|
68
68
|
info.mappingsModulePath->JSON.stringifyAny->Option.getOr(`""`)
|
|
69
69
|
|
|
70
|
+
// Same deploy-time log attribution as the shared-runtime builder: the
|
|
71
|
+
// entry point annotates every invocation with these, and the `comp` string
|
|
72
|
+
// must match the ReScript dispatch boundary's `EventCollector(<name>)`.
|
|
73
|
+
let attribution = Util_LogAttribution.fragments(~comp=`EventCollector(${eventCollectorName})`)
|
|
74
|
+
|
|
70
75
|
let handlerConfigOutput =
|
|
71
76
|
Pulumi.Output.all2((info.queryDbTableName, sourceUrns))
|
|
72
77
|
->Pulumi.Output.apply(((tableName, urns)) => {
|
|
73
78
|
let sourceUrn = urns->Array.getUnsafe(0)
|
|
74
|
-
`{"handlers":[{"specModule":${specModule},"mappingsModule":${mappingsModule},"queryDbTableName":"${tableName}","sourceUrn":"${sourceUrn}"}]}`
|
|
79
|
+
`{"handlers":[{"specModule":${specModule},"mappingsModule":${mappingsModule},"queryDbTableName":"${tableName}","sourceUrn":"${sourceUrn}"${attribution}}]}`
|
|
75
80
|
})
|
|
76
81
|
|
|
77
82
|
let envVars: dict<Pulumi.Input.t<string>> = Dict.make()
|
|
@@ -93,6 +98,7 @@ let forEventCollector: ReventlessCore.Runtime.forEventCollector<
|
|
|
93
98
|
let runtime = RuntimeEnvironment_Lambda.makeFromCodeAsset(
|
|
94
99
|
~name,
|
|
95
100
|
~unitKind=ReventlessCore.Monitoring.EventCollector,
|
|
101
|
+
~componentKind=ReventlessCore.ComponentType.EventCollector,
|
|
96
102
|
~code,
|
|
97
103
|
~sourceCodeHash,
|
|
98
104
|
~envVars,
|
|
@@ -8,6 +8,7 @@ import * as Component$ReventlessCore from "@reventlessdev/reventless-core/src/co
|
|
|
8
8
|
import * as Util_Bundle$ReventlessAws from "../../util/Util_Bundle.res.mjs";
|
|
9
9
|
import * as ComponentType$ReventlessCore from "@reventlessdev/reventless-core/src/ComponentType.res.mjs";
|
|
10
10
|
import * as EventCollector$ReventlessCore from "@reventlessdev/reventless-core/src/components/EventCollector/EventCollector.res.mjs";
|
|
11
|
+
import * as Util_LogAttribution$ReventlessAws from "../../util/Util_LogAttribution.res.mjs";
|
|
11
12
|
import * as RuntimeEnvironment_Lambda$ReventlessAws from "./RuntimeEnvironment_Lambda.res.mjs";
|
|
12
13
|
import * as EventCollectorChannel_DynamoDbStream$ReventlessAws from "../EventCollector/EventCollectorChannel_DynamoDbStream.res.mjs";
|
|
13
14
|
|
|
@@ -46,12 +47,13 @@ function forEventCollector(param, eventTopics, resources, memorySizeOpt, timeout
|
|
|
46
47
|
};
|
|
47
48
|
let specModule = Stdlib_Option.getOr(JSON.stringify(info.specModulePath), `""`);
|
|
48
49
|
let mappingsModule = Stdlib_Option.getOr(JSON.stringify(info.mappingsModulePath), `""`);
|
|
50
|
+
let attribution = Util_LogAttribution$ReventlessAws.fragments(`EventCollector(` + eventCollectorName + `)`);
|
|
49
51
|
let handlerConfigOutput = Pulumi.all([
|
|
50
52
|
info.queryDbTableName,
|
|
51
53
|
sourceUrns
|
|
52
54
|
]).apply(param => {
|
|
53
55
|
let sourceUrn = param[1][0];
|
|
54
|
-
return `{"handlers":[{"specModule":` + specModule + `,"mappingsModule":` + mappingsModule + `,"queryDbTableName":"` + param[0] + `","sourceUrn":"` + sourceUrn + `"}]}`;
|
|
56
|
+
return `{"handlers":[{"specModule":` + specModule + `,"mappingsModule":` + mappingsModule + `,"queryDbTableName":"` + param[0] + `","sourceUrn":"` + sourceUrn + `"` + attribution + `}]}`;
|
|
55
57
|
});
|
|
56
58
|
let envVars = {};
|
|
57
59
|
envVars["HANDLER_CONFIG"] = handlerConfigOutput;
|
|
@@ -61,7 +63,7 @@ function forEventCollector(param, eventTopics, resources, memorySizeOpt, timeout
|
|
|
61
63
|
packageDirs[specPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(specPkg);
|
|
62
64
|
packageDirs[mappingsPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(mappingsPkg);
|
|
63
65
|
let match = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/ReadModelEntryPoint.mjs", packageDirs, undefined);
|
|
64
|
-
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(name, "EventCollector", match.code, match.sourceCodeHash, envVars, memorySize, timeout, undefined, undefined, undefined, undefined, undefined, opts);
|
|
66
|
+
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(name, "EventCollector", "EventCollector", match.code, match.sourceCodeHash, envVars, memorySize, timeout, undefined, undefined, undefined, undefined, undefined, opts);
|
|
65
67
|
EventCollectorChannel_DynamoDbStream$ReventlessAws.connect(name, [{
|
|
66
68
|
channel: channel,
|
|
67
69
|
eventTopics: eventTopics,
|
|
@@ -44,6 +44,13 @@ let registerReadModel = (
|
|
|
44
44
|
|
|
45
45
|
type storedSpec = {
|
|
46
46
|
componentName: string,
|
|
47
|
+
/** The event collector's own resource name (`CustomersReadModel`), as opposed
|
|
48
|
+
to `componentName` (its parent read model, `Customers`). Source of the
|
|
49
|
+
`comp` baked into HANDLER_CONFIG — the deployed entry point annotates logs
|
|
50
|
+
with it, so it must match the ReScript dispatch boundary's
|
|
51
|
+
`EventCollector(<name>)` exactly (see
|
|
52
|
+
docs/plans/entrypoint-dispatch-parity-and-latency-fields.md). */
|
|
53
|
+
eventCollectorName: string,
|
|
47
54
|
parentResource: Pulumi.Resource.t,
|
|
48
55
|
sourceUrns: Pulumi.Output.t<array<string>>,
|
|
49
56
|
channelSpec: ReventlessCore.EventCollector_Adapter.channelSpec<
|
|
@@ -93,6 +100,7 @@ let forEventCollector: ReventlessCore.Runtime.forEventCollector<
|
|
|
93
100
|
storedSpecs
|
|
94
101
|
->Array.push({
|
|
95
102
|
componentName: parentName,
|
|
103
|
+
eventCollectorName,
|
|
96
104
|
parentResource,
|
|
97
105
|
sourceUrns,
|
|
98
106
|
channelSpec: {channel, eventTopics, resources},
|
|
@@ -210,6 +218,15 @@ let finish = () =>
|
|
|
210
218
|
`,"stateTopicName":${topic->JSON.Encode.string->JSON.stringify}`
|
|
211
219
|
}
|
|
212
220
|
: ""
|
|
221
|
+
// Log attribution baked at deploy time: this Lambda hosts every read
|
|
222
|
+
// model, so the shell needs a per-handler `comp` to keep their log
|
|
223
|
+
// lines separable, and a per-handler `plugin` because the shared
|
|
224
|
+
// Lambda's own name carries no single plugin identity. Both are
|
|
225
|
+
// resolved here — the registry LogPrefix consults is a deploy-time
|
|
226
|
+
// structure, empty inside the Lambda.
|
|
227
|
+
let attribution = Util_LogAttribution.fragments(
|
|
228
|
+
~comp=`EventCollector(${spec.eventCollectorName})`,
|
|
229
|
+
)
|
|
213
230
|
let handlerJson =
|
|
214
231
|
Pulumi.Output.all4((
|
|
215
232
|
info.queryDbTableName,
|
|
@@ -221,7 +238,7 @@ let finish = () =>
|
|
|
221
238
|
// No stream resource (Postgres-backed source) → dispatch on the
|
|
222
239
|
// feed queue's ARN instead of a stream URN.
|
|
223
240
|
let sourceUrn = urns->Array.get(0)->Option.getOr(feedArn)
|
|
224
|
-
`{"specModule":${specModule},"mappingsModule":${mappingsModule},"queryDbTableName":"${tableName}","sourceUrn":"${sourceUrn}"${pgFragment}${stateTopicFragment}}`
|
|
241
|
+
`{"specModule":${specModule},"mappingsModule":${mappingsModule},"queryDbTableName":"${tableName}","sourceUrn":"${sourceUrn}"${attribution}${pgFragment}${stateTopicFragment}}`
|
|
225
242
|
})
|
|
226
243
|
let _ = handlerOutputs->Array.push(handlerJson)
|
|
227
244
|
| None =>
|
|
@@ -284,6 +301,7 @@ let finish = () =>
|
|
|
284
301
|
let runtime = RuntimeEnvironment_Lambda.makeFromCodeAsset(
|
|
285
302
|
~name="AllReadModels",
|
|
286
303
|
~unitKind=ReventlessCore.Monitoring.EventCollector,
|
|
304
|
+
~componentKind=ReventlessCore.ComponentType.EventCollector,
|
|
287
305
|
~code,
|
|
288
306
|
~sourceCodeHash,
|
|
289
307
|
~envVars,
|
|
@@ -17,6 +17,7 @@ import * as QueryDbBackend$ReventlessAws from "../QueryDb/QueryDbBackend.res.mjs
|
|
|
17
17
|
import * as EventLogBackend$ReventlessAws from "../EventLog/EventLogBackend.res.mjs";
|
|
18
18
|
import * as Plugin_Helpers$ReventlessCore from "@reventlessdev/reventless-core/src/plugin/component/Plugin_Helpers.res.mjs";
|
|
19
19
|
import * as PgProjectionFeed$ReventlessAws from "../Postgres/PgProjectionFeed.res.mjs";
|
|
20
|
+
import * as Util_LogAttribution$ReventlessAws from "../../util/Util_LogAttribution.res.mjs";
|
|
20
21
|
import * as RuntimeEnvironment_Lambda$ReventlessAws from "./RuntimeEnvironment_Lambda.res.mjs";
|
|
21
22
|
import * as EventCollectorChannel_DynamoDbStream$ReventlessAws from "../EventCollector/EventCollectorChannel_DynamoDbStream.res.mjs";
|
|
22
23
|
|
|
@@ -65,6 +66,7 @@ function forEventCollector(param, eventTopics, resources, memorySizeOpt, timeout
|
|
|
65
66
|
let sourceUrns = Pulumi.all(Component$ReventlessCore.outputs(eventCollector).resources.map(param => param.urn));
|
|
66
67
|
storedSpecs.push({
|
|
67
68
|
componentName: parentName,
|
|
69
|
+
eventCollectorName: eventCollectorName,
|
|
68
70
|
parentResource: parentResource,
|
|
69
71
|
sourceUrns: sourceUrns,
|
|
70
72
|
channelSpec: {
|
|
@@ -128,6 +130,7 @@ function finish() {
|
|
|
128
130
|
} else {
|
|
129
131
|
stateTopicFragment = "";
|
|
130
132
|
}
|
|
133
|
+
let attribution = Util_LogAttribution$ReventlessAws.fragments(`EventCollector(` + spec.eventCollectorName + `)`);
|
|
131
134
|
let handlerJson = Pulumi.all([
|
|
132
135
|
info.queryDbTableName,
|
|
133
136
|
spec.sourceUrns,
|
|
@@ -135,7 +138,7 @@ function finish() {
|
|
|
135
138
|
handlerPgFragment
|
|
136
139
|
]).apply(param => {
|
|
137
140
|
let sourceUrn = Stdlib_Option.getOr(param[1][0], param[2]);
|
|
138
|
-
return `{"specModule":` + specModule + `,"mappingsModule":` + mappingsModule + `,"queryDbTableName":"` + param[0] + `","sourceUrn":"` + sourceUrn + `"` + param[3] + stateTopicFragment + `}`;
|
|
141
|
+
return `{"specModule":` + specModule + `,"mappingsModule":` + mappingsModule + `,"queryDbTableName":"` + param[0] + `","sourceUrn":"` + sourceUrn + `"` + attribution + param[3] + stateTopicFragment + `}`;
|
|
139
142
|
});
|
|
140
143
|
handlerOutputs.push(handlerJson);
|
|
141
144
|
});
|
|
@@ -158,7 +161,7 @@ function finish() {
|
|
|
158
161
|
subnetIds: qdbSelection.subnetIds,
|
|
159
162
|
securityGroupIds: [sgId]
|
|
160
163
|
})) : undefined;
|
|
161
|
-
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset("AllReadModels", "EventCollector", match$1.code, match$1.sourceCodeHash, envVars, match[0], match[1], undefined, undefined, undefined, undefined, vpcConfig, opts);
|
|
164
|
+
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset("AllReadModels", "EventCollector", "EventCollector", match$1.code, match$1.sourceCodeHash, envVars, match[0], match[1], undefined, undefined, undefined, undefined, vpcConfig, opts);
|
|
162
165
|
if (qdbSelection !== undefined && anyPgBacked) {
|
|
163
166
|
qdbSelection.connectionConfig.apply(cc => new (Aws.iam.RolePolicy)("AllReadModels-pgSecret", {
|
|
164
167
|
policy: PolicyDocument$PulumiAws.toJsonString(PolicyDocument$PulumiAws.make(undefined, "AllReadModels-pgSecretPolicy", [{
|