vybekiit 0.7.4 → 0.7.7
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/dist/bin.js +10483 -1704
- package/dist/global-skills/aws-cdk/SKILL.md +2 -1
- package/dist/global-skills/aws-cloudformation/SKILL.md +2 -1
- package/dist/global-skills/aws-serverless/SKILL.md +45 -44
- package/dist/global-skills/aws-serverless/assets/powertools-handler.py +2 -1
- package/dist/global-skills/aws-serverless/references/api-gateway.md +50 -470
- package/dist/global-skills/aws-serverless/references/architecture.md +47 -186
- package/dist/global-skills/aws-serverless/references/concurrency.md +44 -158
- package/dist/global-skills/aws-serverless/references/deployment.md +1 -1
- package/dist/global-skills/aws-serverless/references/event-sources.md +72 -391
- package/dist/global-skills/aws-serverless/references/lambda.md +69 -428
- package/dist/global-skills/aws-serverless/references/orchestration.md +65 -384
- package/dist/global-skills/aws-serverless/references/production.md +78 -415
- package/dist/global-skills/aws-serverless/references/troubleshooting.md +92 -619
- package/dist/global-skills/claimable-postgres/SKILL.md +60 -49
- package/dist/global-skills/design-my-data/SKILL.md +2 -0
- package/dist/global-skills/eas-app-stores/SKILL.md +8 -0
- package/dist/global-skills/eas-app-stores/references/play-store.md +2 -0
- package/dist/global-skills/eas-hosting/SKILL.md +8 -0
- package/dist/global-skills/eas-observe/SKILL.md +30 -8
- package/dist/global-skills/eas-observe/agents/openai.yaml +1 -1
- package/dist/global-skills/eas-observe/references/metrics.md +54 -3
- package/dist/global-skills/eas-observe/references/queries.md +78 -17
- package/dist/global-skills/eas-observe/references/setup.md +164 -5
- package/dist/global-skills/eas-observe/references/third-party.md +136 -0
- package/dist/global-skills/eas-simulator/SKILL.md +63 -11
- package/dist/global-skills/eas-simulator/references/controllers.md +21 -2
- package/dist/global-skills/eas-simulator/references/run-your-app.md +16 -11
- package/dist/global-skills/eas-simulator/references/troubleshooting.md +8 -5
- package/dist/global-skills/eas-update-insights/SKILL.md +8 -0
- package/dist/global-skills/eas-workflows/SKILL.md +15 -10
- package/dist/global-skills/eas-workflows/scripts/package.json +2 -7
- package/dist/global-skills/email-best-practices/.github/workflows/sync-skills.yml +30 -0
- package/dist/global-skills/email-best-practices/README.md +63 -0
- package/dist/global-skills/email-best-practices/references/accessibility.md +189 -0
- package/dist/global-skills/email-best-practices/references/compliance.md +125 -0
- package/dist/global-skills/email-best-practices/references/deliverability.md +121 -0
- package/dist/global-skills/email-best-practices/references/email-capture.md +129 -0
- package/dist/global-skills/email-best-practices/references/email-types.md +173 -0
- package/dist/global-skills/email-best-practices/references/list-management.md +157 -0
- package/dist/global-skills/email-best-practices/references/marketing-emails.md +115 -0
- package/dist/global-skills/email-best-practices/references/sending-reliability.md +155 -0
- package/dist/global-skills/email-best-practices/references/transactional-email-catalog.md +418 -0
- package/dist/global-skills/email-best-practices/references/transactional-emails.md +92 -0
- package/dist/global-skills/email-best-practices/references/webhooks-events.md +167 -0
- package/dist/global-skills/email-best-practices/tests/README.md +35 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/01-spam-deliverability.md +46 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/02-multi-region-compliance.md +48 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/03-retry-idempotency.md +36 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/04-webhook-bounce-handling.md +52 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/05-new-saas-email-plan.md +51 -0
- package/dist/global-skills/expo-animation/LICENSE +21 -0
- package/dist/global-skills/expo-animation/RECIPES.md +385 -0
- package/dist/global-skills/expo-animation/SKILL.md +267 -0
- package/dist/global-skills/expo-animation/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-app-clip/SKILL.md +8 -0
- package/dist/global-skills/expo-brownfield/SKILL.md +8 -0
- package/dist/global-skills/expo-brownfield/references/brownfield-isolated.md +53 -4
- package/dist/global-skills/expo-data-fetching/SKILL.md +8 -0
- package/dist/global-skills/expo-design-system/SKILL.md +356 -0
- package/dist/global-skills/expo-design-system/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-design-system/references/audit.md +185 -0
- package/dist/global-skills/expo-dev-client/SKILL.md +8 -0
- package/dist/global-skills/expo-dom/SKILL.md +8 -0
- package/dist/global-skills/expo-examples/SKILL.md +8 -0
- package/dist/global-skills/expo-migrate-module/SKILL.md +113 -0
- package/dist/global-skills/expo-migrate-module/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-migrate-module/references/compatibility.md +73 -0
- package/dist/global-skills/expo-migrate-module/references/example.md +212 -0
- package/dist/global-skills/expo-migrate-module/references/migration-map.md +306 -0
- package/dist/global-skills/expo-module/SKILL.md +11 -1
- package/dist/global-skills/expo-native-ui/SKILL.md +8 -0
- package/dist/global-skills/expo-project-structure/SKILL.md +114 -0
- package/dist/global-skills/expo-project-structure/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-router/SKILL.md +8 -0
- package/dist/global-skills/expo-skill-feedback/SKILL.md +66 -33
- package/dist/global-skills/expo-skill-feedback/agents/openai.yaml +2 -2
- package/dist/global-skills/expo-tailwind-setup/SKILL.md +8 -0
- package/dist/global-skills/expo-ui/SKILL.md +8 -0
- package/dist/global-skills/expo-upgrade/SKILL.md +15 -1
- package/dist/global-skills/expo-web-to-native/SKILL.md +8 -0
- package/dist/global-skills/extension-to-functions-codebase/SKILL.md +129 -0
- package/dist/global-skills/extension-to-functions-codebase/references/configuration-migration.md +161 -0
- package/dist/global-skills/extension-to-functions-codebase/references/destructuring-shim.md +122 -0
- package/dist/global-skills/extension-to-functions-codebase/references/signature-mapping.md +84 -0
- package/dist/global-skills/firebase-ai-logic-basics/SKILL.md +61 -19
- package/dist/global-skills/firebase-ai-logic-basics/references/flutter_setup.md +6 -3
- package/dist/global-skills/firebase-app-hosting-basics/SKILL.md +5 -1
- package/dist/global-skills/firebase-auth-basics/SKILL.md +4 -2
- package/dist/global-skills/firebase-basics/SKILL.md +5 -5
- package/dist/global-skills/firebase-crashlytics/SKILL.md +2 -0
- package/dist/global-skills/firebase-data-connect/SKILL.md +2 -0
- package/dist/global-skills/firebase-firestore/SKILL.md +3 -6
- package/dist/global-skills/firebase-hosting-basics/SKILL.md +4 -1
- package/dist/global-skills/firebase-remote-config-basics/SKILL.md +5 -1
- package/dist/global-skills/firebase-security-rules-auditor/SKILL.md +4 -1
- package/dist/global-skills/harden/SKILL.md +2 -1
- package/dist/global-skills/instrument-feature-flags/SKILL.md +1 -0
- package/dist/global-skills/instrument-feature-flags/references/COMMANDMENTS.md +5 -0
- package/dist/global-skills/instrument-feature-flags/references/adding-feature-flag-code.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/android.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/api.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/best-practices.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/django.md +38 -5
- package/dist/global-skills/instrument-feature-flags/references/dotnet.md +10 -4
- package/dist/global-skills/instrument-feature-flags/references/elixir.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/flask.md +17 -5
- package/dist/global-skills/instrument-feature-flags/references/flutter.md +7 -5
- package/dist/global-skills/instrument-feature-flags/references/go.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/ios.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/java.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/laravel.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/next-js.md +74 -8
- package/dist/global-skills/instrument-feature-flags/references/nodejs.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/php.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/python.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/react-native.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/react.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/ruby-on-rails.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/ruby.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/rust.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/usage.md +41 -4
- package/dist/global-skills/instrument-feature-flags/references/web.md +7 -5
- package/dist/global-skills/instrument-product-analytics/SKILL.md +2 -1
- package/dist/global-skills/instrument-product-analytics/references/COMMANDMENTS.md +5 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-hybrid.md +12 -14
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-ssr.md +25 -21
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-django.md +75 -55
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-fastapi.md +3 -6
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-flask.md +26 -16
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-nuxt-3-6.md +8 -5
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-nuxt-4.md +4 -4
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-react-react-router-7-framework.md +3 -3
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-ruby-on-rails.md +8 -4
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-tanstack-start.md +20 -8
- package/dist/global-skills/instrument-product-analytics/references/android.md +46 -4
- package/dist/global-skills/instrument-product-analytics/references/angular.md +41 -5
- package/dist/global-skills/instrument-product-analytics/references/astro.md +41 -5
- package/dist/global-skills/instrument-product-analytics/references/configuration.md +7 -4
- package/dist/global-skills/instrument-product-analytics/references/django.md +38 -5
- package/dist/global-skills/instrument-product-analytics/references/dotnet.md +10 -4
- package/dist/global-skills/instrument-product-analytics/references/elixir.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/flask.md +17 -5
- package/dist/global-skills/instrument-product-analytics/references/flutter.md +49 -4
- package/dist/global-skills/instrument-product-analytics/references/go.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/identify-users.md +38 -7
- package/dist/global-skills/instrument-product-analytics/references/ios.md +14 -4
- package/dist/global-skills/instrument-product-analytics/references/laravel.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/next-js.md +74 -8
- package/dist/global-skills/instrument-product-analytics/references/nuxt-js-3-6.md +39 -7
- package/dist/global-skills/instrument-product-analytics/references/nuxt-js.md +40 -4
- package/dist/global-skills/instrument-product-analytics/references/php.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/posthog-python.md +21 -17
- package/dist/global-skills/instrument-product-analytics/references/python.md +15 -5
- package/dist/global-skills/instrument-product-analytics/references/react-native.md +41 -7
- package/dist/global-skills/instrument-product-analytics/references/react-router-v6.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-data-mode.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-declarative-mode.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-framework-mode.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/ruby-on-rails.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/ruby.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/svelte.md +42 -6
- package/dist/global-skills/instrument-product-analytics/references/tanstack-start.md +31 -7
- package/dist/global-skills/instrument-product-analytics/references/usage.md +41 -4
- package/dist/global-skills/instrument-product-analytics/references/vue-js.md +42 -6
- package/dist/global-skills/manifest.json +6 -1
- package/dist/global-skills/neon/SKILL.md +235 -121
- package/dist/global-skills/neon-ai-gateway/SKILL.md +95 -16
- package/dist/global-skills/neon-functions/SKILL.md +242 -152
- package/dist/global-skills/neon-functions/references/ai-sdk.md +9 -3
- package/dist/global-skills/neon-functions/references/mastra-studio.md +1 -1
- package/dist/global-skills/neon-functions/references/mcp.md +13 -4
- package/dist/global-skills/neon-functions/references/sentry.md +165 -52
- package/dist/global-skills/neon-functions/references/sse.md +23 -6
- package/dist/global-skills/neon-object-storage/SKILL.md +40 -16
- package/dist/global-skills/neon-postgres/SKILL.md +63 -262
- package/dist/global-skills/neon-postgres-branches/SKILL.md +61 -50
- package/dist/global-skills/neon-postgres-egress-optimizer/SKILL.md +22 -3
- package/dist/global-skills/resend/SKILL.md +6 -6
- package/dist/global-skills/resend/references/automations.md +2 -2
- package/dist/global-skills/resend/references/broadcasts.md +11 -3
- package/dist/global-skills/resend/references/domains.md +25 -3
- package/dist/global-skills/resend/references/installation.md +7 -7
- package/dist/global-skills/setup-payments/SKILL.md +4 -5
- package/dist/global-skills/stripe-best-practices/SKILL.md +32 -7
- package/dist/global-skills/stripe-best-practices/references/billing.md +11 -1
- package/dist/global-skills/stripe-best-practices/references/payments.md +23 -2
- package/dist/global-skills/stripe-best-practices/references/security.md +21 -11
- package/dist/global-skills/stripe-best-practices/references/tax.md +116 -11
- package/dist/global-skills/supabase/CHANGELOG.md +25 -0
- package/dist/global-skills/supabase/SKILL.md +5 -1
- package/dist/global-skills/supabase-postgres-best-practices/CHANGELOG.md +30 -0
- package/dist/global-skills/supabase-postgres-best-practices/SKILL.md +1 -1
- package/dist/global-skills/use-kit-mcp/SKILL.md +5 -5
- package/dist/global-skills/use-railway/SKILL.md +4 -4
- package/dist/global-skills/use-railway/references/iac.md +206 -57
- package/dist/global-skills/use-railway/scripts/railway-api.sh +7 -2
- package/dist/global-skills/xcode-project-setup/SKILL.md +2 -0
- package/package.json +12 -9
- package/LICENSE.md +0 -47
- package/dist/global-skills/eas-workflows/scripts/validate.js +0 -84
- package/dist/global-skills/expo-skill-feedback/scripts/skill-feedback.cjs +0 -118
- package/dist/global-skills/neon-functions/references/hono-websockets.md +0 -145
|
@@ -1,484 +1,165 @@
|
|
|
1
1
|
# Lambda Event Sources Reference
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Event source mapping (ESM) config parameters, scaling numbers, and filtering gotchas. Assumes you know the basics (SNS pushes asynchronously and is a direct trigger not an ESM; `ReportBatchItemFailures` returns `{batchItemFailures: [{itemIdentifier}]}`; unmatched SQS filter messages are permanently deleted; SQS visibility timeout ≥ 6× function timeout) — this file focuses on the exact values and edge cases.
|
|
4
4
|
|
|
5
5
|
## Contents
|
|
6
6
|
|
|
7
7
|
- [SQS event source mapping](#sqs-event-source-mapping)
|
|
8
8
|
- [DynamoDB Streams triggers](#dynamodb-streams-triggers)
|
|
9
|
-
- [SNS subscriptions](#sns-subscriptions)
|
|
10
9
|
- [Event filtering](#event-filtering)
|
|
11
10
|
- [Partial batch failure reporting](#partial-batch-failure-reporting)
|
|
12
|
-
- [Error handling
|
|
11
|
+
- [Error handling and concurrency](#error-handling-and-concurrency)
|
|
13
12
|
|
|
14
13
|
---
|
|
15
14
|
|
|
16
15
|
## SQS event source mapping
|
|
17
16
|
|
|
18
|
-
Lambda polls SQS
|
|
19
|
-
|
|
20
|
-
### Configuration parameters
|
|
17
|
+
Lambda long-polls SQS and invokes your function **synchronously** with a batch.
|
|
21
18
|
|
|
22
19
|
| Parameter | Default | Range / Notes |
|
|
23
20
|
|-----------|---------|---------------|
|
|
24
21
|
| `BatchSize` | 10 | Standard: max 10,000. FIFO: max 10 |
|
|
25
|
-
| `MaximumBatchingWindowInSeconds` | 0 | 0–300. Not
|
|
26
|
-
| `MaximumConcurrency` | — | 2–1,000. Per-ESM
|
|
22
|
+
| `MaximumBatchingWindowInSeconds` | 0 | 0–300. Not for FIFO. Requires ≥ 1s when BatchSize > 10 |
|
|
23
|
+
| `MaximumConcurrency` | — | 2–1,000. Per-ESM cap |
|
|
27
24
|
| `ProvisionedPollerConfig.MinimumPollers` | 2 | 2–200 |
|
|
28
|
-
| `ProvisionedPollerConfig.MaximumPollers` | 200 |
|
|
25
|
+
| `ProvisionedPollerConfig.MaximumPollers` | 200 | 1–2,000 |
|
|
29
26
|
| `FilterCriteria` | — | Filters on `body` key only |
|
|
30
27
|
| `FunctionResponseTypes` | — | Set to `ReportBatchItemFailures` |
|
|
31
28
|
|
|
32
|
-
> **MaximumConcurrency and Provisioned Mode are mutually exclusive
|
|
33
|
-
|
|
34
|
-
### Batching behavior
|
|
35
|
-
|
|
36
|
-
Lambda invokes when **any** condition is met:
|
|
37
|
-
|
|
38
|
-
1. Batching window expires
|
|
39
|
-
2. Batch size reached
|
|
40
|
-
3. Payload reaches 6 MB
|
|
41
|
-
|
|
42
|
-
### Scaling behavior
|
|
43
|
-
|
|
44
|
-
**Standard queues:**
|
|
45
|
-
|
|
46
|
-
- Starts with **5** concurrent invocations
|
|
47
|
-
- Scales up by **300/min**
|
|
48
|
-
- Default maximum: **1,250** concurrent invocations
|
|
49
|
-
- Provisioned mode: up to **20,000** (scales 3× faster at 1,000/min)
|
|
50
|
-
|
|
51
|
-
**FIFO queues:**
|
|
29
|
+
> **MaximumConcurrency and Provisioned Mode are mutually exclusive** on the same ESM.
|
|
52
30
|
|
|
53
|
-
|
|
54
|
-
- Messages delivered in order per message group ID
|
|
31
|
+
Lambda invokes when **any** of: batching window expires, batch size reached, or payload hits 6 MB.
|
|
55
32
|
|
|
56
|
-
###
|
|
33
|
+
### Scaling
|
|
57
34
|
|
|
58
|
-
|
|
59
|
-
- Set visibility timeout to **≥ 6× function timeout** to prevent premature retry
|
|
60
|
-
- On function error, entire batch becomes visible again after visibility timeout
|
|
61
|
-
- On throttle, Lambda backs off; messages reappear after visibility timeout
|
|
35
|
+
**Standard queues:** concurrency **starts at 5** concurrent invocations and scales up by **~300 per minute** to a **default maximum of 1,250** — so a sudden burst (e.g. a backlog of 10,000 messages) is not absorbed immediately; it takes several minutes to ramp. For high scale-out or high-throughput workloads, use **Provisioned Mode**, which starts higher, ramps significantly faster, and reaches a much larger ceiling. The 1,250 default is also bounded by account concurrency; confirm current account limits with `aws service-quotas get-service-quota --service-code lambda`.
|
|
62
36
|
|
|
63
|
-
|
|
37
|
+
**FIFO queues:** concurrency capped by the **lower** of (number of message group IDs, `MaximumConcurrency`); order preserved per group ID.
|
|
64
38
|
|
|
65
39
|
```yaml
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
ScalingConfig:
|
|
81
|
-
MaximumConcurrency: 50
|
|
82
|
-
FilterCriteria:
|
|
83
|
-
Filters:
|
|
84
|
-
- Pattern: '{"body": {"status": ["PENDING"]}}'
|
|
40
|
+
# SAM
|
|
41
|
+
Events:
|
|
42
|
+
SQSEvent:
|
|
43
|
+
Type: SQS
|
|
44
|
+
Properties:
|
|
45
|
+
Queue: !GetAtt MyQueue.Arn
|
|
46
|
+
BatchSize: 10
|
|
47
|
+
MaximumBatchingWindowInSeconds: 5
|
|
48
|
+
FunctionResponseTypes: [ReportBatchItemFailures]
|
|
49
|
+
ScalingConfig:
|
|
50
|
+
MaximumConcurrency: 50
|
|
51
|
+
FilterCriteria:
|
|
52
|
+
Filters:
|
|
53
|
+
- Pattern: '{"body": {"status": ["PENDING"]}}'
|
|
85
54
|
```
|
|
86
55
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
```typescript
|
|
90
|
-
import { SqsEventSource } from 'aws-cdk-lib/aws-lambda-event-sources';
|
|
91
|
-
import * as sqs from 'aws-cdk-lib/aws-sqs';
|
|
92
|
-
|
|
93
|
-
const dlq = new sqs.Queue(this, 'DLQ');
|
|
94
|
-
const queue = new sqs.Queue(this, 'MyQueue', {
|
|
95
|
-
visibilityTimeout: Duration.seconds(300), // 6× function timeout
|
|
96
|
-
deadLetterQueue: { queue: dlq, maxReceiveCount: 3 },
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
fn.addEventSource(new SqsEventSource(queue, {
|
|
100
|
-
batchSize: 10,
|
|
101
|
-
maxBatchingWindow: Duration.seconds(5),
|
|
102
|
-
reportBatchItemFailures: true,
|
|
103
|
-
maxConcurrency: 50,
|
|
104
|
-
}));
|
|
105
|
-
```
|
|
56
|
+
CDK: `fn.addEventSource(new SqsEventSource(queue, { batchSize, maxBatchingWindow, reportBatchItemFailures: true, maxConcurrency }))`. Harden the queue: `new sqs.Queue(this, 'MyQueue', { encryption: sqs.QueueEncryption.SQS_MANAGED, enforceSSL: true, ... })` (set the same on the DLQ).
|
|
106
57
|
|
|
107
58
|
---
|
|
108
59
|
|
|
109
60
|
## DynamoDB Streams triggers
|
|
110
61
|
|
|
111
|
-
Lambda polls
|
|
112
|
-
|
|
113
|
-
### Configuration parameters
|
|
62
|
+
Lambda polls stream shards **4×/second**; invokes synchronously, in-order per partition key.
|
|
114
63
|
|
|
115
64
|
| Parameter | Default | Range / Notes |
|
|
116
65
|
|-----------|---------|---------------|
|
|
117
66
|
| `BatchSize` | 100 | Max 10,000 |
|
|
118
|
-
| `MaximumBatchingWindowInSeconds` | 0 | 0–300 |
|
|
119
67
|
| `StartingPosition` | — | `TRIM_HORIZON` (recommended) or `LATEST` |
|
|
120
68
|
| `ParallelizationFactor` | 1 | 1–10. Concurrent batches per shard |
|
|
121
|
-
| `BisectBatchOnFunctionError` | false | Split failed batch in half |
|
|
69
|
+
| `BisectBatchOnFunctionError` | false | Split failed batch in half; does NOT consume retry quota |
|
|
122
70
|
| `MaximumRetryAttempts` | -1 (infinite) | 0–10,000 |
|
|
123
|
-
| `MaximumRecordAgeInSeconds` | -1 (infinite) | -1
|
|
71
|
+
| `MaximumRecordAgeInSeconds` | -1 (infinite) | -1 (infinite), or 60–604,800 (7 days); 0–59 rejected |
|
|
124
72
|
| `DestinationConfig.OnFailure` | — | SQS, SNS, S3, or Kafka topic |
|
|
125
|
-
| `
|
|
126
|
-
| `FunctionResponseTypes` | — | `ReportBatchItemFailures` |
|
|
127
|
-
| `TumblingWindowInSeconds` | — | 0–900 for stateful aggregation |
|
|
73
|
+
| `TumblingWindowInSeconds` | — | 0–900, for stateful aggregation |
|
|
128
74
|
|
|
129
75
|
### Key behaviors
|
|
130
76
|
|
|
131
|
-
- **
|
|
132
|
-
- **
|
|
133
|
-
-
|
|
134
|
-
- **
|
|
135
|
-
- DynamoDB stream retention is **24 hours** — a poison record can block a shard for that entire window without retry limits
|
|
136
|
-
|
|
137
|
-
### SAM template
|
|
77
|
+
- **Max 2 Lambda readers per shard** (single-region tables). Global tables: limit to **1**.
|
|
78
|
+
- **TRIM_HORIZON** recommended — `LATEST` may miss events during ESM creation.
|
|
79
|
+
- 100 shards × ParallelizationFactor 10 = up to **1,000 concurrent invocations** (order maintained at partition-key level).
|
|
80
|
+
- **Stream retention is 24 hours** — a poison record can block a shard for that entire window if retries aren't bounded. Set `MaximumRetryAttempts` / `MaximumRecordAgeInSeconds` / `BisectBatchOnFunctionError`.
|
|
138
81
|
|
|
139
82
|
```yaml
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
BisectBatchOnFunctionError: true
|
|
155
|
-
MaximumRetryAttempts: 3
|
|
156
|
-
MaximumRecordAgeInSeconds: 3600
|
|
157
|
-
FunctionResponseTypes:
|
|
158
|
-
- ReportBatchItemFailures
|
|
159
|
-
DestinationConfig:
|
|
160
|
-
OnFailure:
|
|
161
|
-
Destination: !GetAtt FailureQueue.Arn
|
|
162
|
-
FilterCriteria:
|
|
163
|
-
Filters:
|
|
164
|
-
- Pattern: '{"eventName": ["INSERT"]}'
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
### CDK example
|
|
168
|
-
|
|
169
|
-
```typescript
|
|
170
|
-
import { DynamoEventSource, SqsDlq } from 'aws-cdk-lib/aws-lambda-event-sources';
|
|
171
|
-
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
|
|
172
|
-
|
|
173
|
-
const table = new dynamodb.Table(this, 'MyTable', {
|
|
174
|
-
partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
|
|
175
|
-
stream: dynamodb.StreamViewType.NEW_AND_OLD_IMAGES,
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
fn.addEventSource(new DynamoEventSource(table, {
|
|
179
|
-
startingPosition: lambda.StartingPosition.TRIM_HORIZON,
|
|
180
|
-
batchSize: 100,
|
|
181
|
-
maxBatchingWindow: Duration.seconds(5),
|
|
182
|
-
parallelizationFactor: 5,
|
|
183
|
-
bisectBatchOnError: true,
|
|
184
|
-
retryAttempts: 3,
|
|
185
|
-
maxRecordAge: Duration.hours(1),
|
|
186
|
-
reportBatchItemFailures: true,
|
|
187
|
-
onFailure: new SqsDlq(dlq),
|
|
188
|
-
}));
|
|
83
|
+
# SAM
|
|
84
|
+
Events:
|
|
85
|
+
DynamoDBStream:
|
|
86
|
+
Type: DynamoDB
|
|
87
|
+
Properties:
|
|
88
|
+
Stream: !GetAtt MyTable.StreamArn
|
|
89
|
+
StartingPosition: TRIM_HORIZON
|
|
90
|
+
ParallelizationFactor: 5
|
|
91
|
+
BisectBatchOnFunctionError: true
|
|
92
|
+
MaximumRetryAttempts: 3
|
|
93
|
+
FunctionResponseTypes: [ReportBatchItemFailures]
|
|
94
|
+
DestinationConfig:
|
|
95
|
+
OnFailure:
|
|
96
|
+
Destination: !GetAtt FailureQueue.Arn
|
|
189
97
|
```
|
|
190
98
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
## SNS subscriptions
|
|
194
|
-
|
|
195
|
-
SNS invokes Lambda **asynchronously** — it is a **direct trigger, NOT an event source mapping**. No polling involved; SNS pushes events to Lambda.
|
|
196
|
-
|
|
197
|
-
### Key characteristics
|
|
198
|
-
|
|
199
|
-
- **Standard topics only** (not FIFO)
|
|
200
|
-
- At-least-once delivery — make functions idempotent
|
|
201
|
-
- SNS retries at increasing intervals over several hours if Lambda is unreachable
|
|
202
|
-
- Cross-account subscriptions supported
|
|
203
|
-
|
|
204
|
-
### Filter policies
|
|
205
|
-
|
|
206
|
-
Filter policies are managed by **SNS** (not Lambda `FilterCriteria`). Set `FilterPolicyScope` to control what is filtered:
|
|
207
|
-
|
|
208
|
-
| Scope | Filters on |
|
|
209
|
-
|-------|-----------|
|
|
210
|
-
| `MessageAttributes` (default) | SNS message attributes |
|
|
211
|
-
| `MessageBody` | JSON body content |
|
|
99
|
+
Encrypt the source table at rest — CDK `new dynamodb.Table(this, 'MyTable', { encryption: dynamodb.TableEncryption.AWS_MANAGED, ... })`, or a customer managed KMS key when compliance requires key control.
|
|
212
100
|
|
|
213
|
-
|
|
214
|
-
{
|
|
215
|
-
"event_type": ["order_placed"],
|
|
216
|
-
"price_usd": [{"numeric": [">=", 100]}],
|
|
217
|
-
"store": [{"anything-but": "test_store"}]
|
|
218
|
-
}
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
### SAM template
|
|
222
|
-
|
|
223
|
-
```yaml
|
|
224
|
-
ProcessorFunction:
|
|
225
|
-
Type: AWS::Serverless::Function
|
|
226
|
-
Properties:
|
|
227
|
-
Handler: processor.handler
|
|
228
|
-
Runtime: nodejs22.x
|
|
229
|
-
Events:
|
|
230
|
-
SNSEvent:
|
|
231
|
-
Type: SNS
|
|
232
|
-
Properties:
|
|
233
|
-
Topic: !Ref MyTopic
|
|
234
|
-
FilterPolicy:
|
|
235
|
-
event_type:
|
|
236
|
-
- order_placed
|
|
237
|
-
FilterPolicyScope: MessageAttributes
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
### CDK example
|
|
241
|
-
|
|
242
|
-
```typescript
|
|
243
|
-
import * as sns from 'aws-cdk-lib/aws-sns';
|
|
244
|
-
import * as subscriptions from 'aws-cdk-lib/aws-sns-subscriptions';
|
|
245
|
-
|
|
246
|
-
topic.addSubscription(new subscriptions.LambdaSubscription(fn, {
|
|
247
|
-
filterPolicy: {
|
|
248
|
-
event_type: sns.SubscriptionFilter.stringFilter({
|
|
249
|
-
allowlist: ['order_placed'],
|
|
250
|
-
}),
|
|
251
|
-
price: sns.SubscriptionFilter.numericFilter({
|
|
252
|
-
greaterThanOrEqualTo: 100,
|
|
253
|
-
}),
|
|
254
|
-
},
|
|
255
|
-
}));
|
|
256
|
-
```
|
|
101
|
+
SNS filter policies (not Lambda `FilterCriteria`) are SNS-managed; set `FilterPolicyScope` to `MessageAttributes` (default) or `MessageBody`.
|
|
257
102
|
|
|
258
103
|
---
|
|
259
104
|
|
|
260
105
|
## Event filtering
|
|
261
106
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
### Supported sources and filter keys
|
|
107
|
+
`FilterCriteria` applies to ESMs only (not SNS/push triggers).
|
|
265
108
|
|
|
266
109
|
| Source | Filter key | Notes |
|
|
267
110
|
|--------|-----------|-------|
|
|
268
|
-
| SQS | `body` | Unmatched messages **automatically deleted** |
|
|
269
|
-
| DynamoDB Streams | `dynamodb`
|
|
111
|
+
| SQS | `body` | Unmatched messages **automatically (permanently) deleted** |
|
|
112
|
+
| DynamoDB Streams | `dynamodb` + metadata (e.g. `eventName`) | **Does NOT support numeric operators** |
|
|
270
113
|
| Kinesis | `data` | Base64-decoded before filtering |
|
|
271
114
|
| MSK / Kafka | `value` | — |
|
|
272
|
-
| Amazon MQ | `data` | — |
|
|
273
115
|
|
|
274
|
-
|
|
116
|
+
- Up to **5 filters** per ESM (request increase to 10). Multiple filters are **OR**'d; fields within one filter are **AND**'d.
|
|
117
|
+
- **DynamoDB numeric filtering is unsupported** — numbers are stored as strings in the DynamoDB stream JSON. Use `{"S": [...]}`/`{"N": ["123"]}` string matches, not `{"numeric": [...]}`.
|
|
118
|
+
- Format mismatch drops the record: if the incoming body is plain string but the filter is JSON (or vice versa), Lambda drops the message.
|
|
275
119
|
|
|
276
|
-
-
|
|
277
|
-
- Multiple filters are **ORed** — record matches if any filter matches
|
|
278
|
-
- Fields within a single filter are **ANDed**
|
|
279
|
-
|
|
280
|
-
### Filter rule operators
|
|
281
|
-
|
|
282
|
-
| Operator | Syntax | Example |
|
|
283
|
-
|----------|--------|---------|
|
|
284
|
-
| Equals | `["value"]` | `"City": ["Seattle"]` |
|
|
285
|
-
| Equals (ignore case) | `[{"equals-ignore-case": "value"}]` | `"City": [{"equals-ignore-case": "seattle"}]` |
|
|
286
|
-
| Null | `[null]` | `"UserID": [null]` |
|
|
287
|
-
| Empty | `[""]` | `"Name": [""]` |
|
|
288
|
-
| Not | `[{"anything-but": ["value"]}]` | `"Weather": [{"anything-but": ["Raining"]}]` |
|
|
289
|
-
| Numeric equals | `[{"numeric": ["=", 100]}]` | `"Price": [{"numeric": ["=", 100]}]` |
|
|
290
|
-
| Numeric range | `[{"numeric": [">", 10, "<=", 20]}]` | `"Price": [{"numeric": [">", 10, "<=", 20]}]` |
|
|
291
|
-
| Exists | `[{"exists": true}]` | `"Field": [{"exists": true}]` |
|
|
292
|
-
| Prefix | `[{"prefix": "us-"}]` | `"Region": [{"prefix": "us-"}]` |
|
|
293
|
-
| Suffix | `[{"suffix": ".png"}]` | `"FileName": [{"suffix": ".png"}]` |
|
|
294
|
-
| Or (fields) | `"$or": [{...}, {...}]` | `"$or": [{"City": ["NY"]}, {"Day": ["Mon"]}]` |
|
|
295
|
-
|
|
296
|
-
> **DynamoDB filtering does NOT support numeric operators.** Numbers are stored as strings in the DynamoDB JSON record.
|
|
297
|
-
|
|
298
|
-
### Body/data format matching
|
|
299
|
-
|
|
300
|
-
| Incoming format | Filter format | Result |
|
|
301
|
-
|----------------|---------------|--------|
|
|
302
|
-
| Plain string | Plain string | Filters normally |
|
|
303
|
-
| Plain string | Valid JSON | Lambda drops the message |
|
|
304
|
-
| Valid JSON | Plain string | Lambda drops the message |
|
|
305
|
-
| Valid JSON | Valid JSON | Filters normally |
|
|
306
|
-
|
|
307
|
-
### Filter examples
|
|
120
|
+
Operators: `["value"]`, `{"equals-ignore-case"}`, `[null]`, `[""]`, `{"anything-but"}`, `{"numeric": [">", 10, "<=", 20]}`, `{"exists": true}`, `{"prefix"}`, `{"suffix"}`, `"$or": [...]`.
|
|
308
121
|
|
|
309
122
|
```yaml
|
|
310
|
-
#
|
|
311
|
-
FilterCriteria:
|
|
312
|
-
Filters:
|
|
313
|
-
- Pattern: '{"body": {"RequestCode": ["BBBB"]}}'
|
|
314
|
-
|
|
315
|
-
# DynamoDB — INSERT events only
|
|
123
|
+
# DynamoDB — INSERT events only / by NewImage attribute (string match, not numeric)
|
|
316
124
|
FilterCriteria:
|
|
317
125
|
Filters:
|
|
318
126
|
- Pattern: '{"eventName": ["INSERT"]}'
|
|
319
|
-
|
|
320
|
-
# DynamoDB — filter by NewImage attribute
|
|
321
|
-
FilterCriteria:
|
|
322
|
-
Filters:
|
|
323
127
|
- Pattern: '{"dynamodb": {"NewImage": {"status": {"S": ["ACTIVE"]}}}}'
|
|
324
|
-
|
|
325
|
-
# Kinesis — filter decoded data
|
|
326
|
-
FilterCriteria:
|
|
327
|
-
Filters:
|
|
328
|
-
- Pattern: '{"data": {"status": ["ACTIVE"]}}'
|
|
329
128
|
```
|
|
330
129
|
|
|
331
130
|
---
|
|
332
131
|
|
|
333
132
|
## Partial batch failure reporting
|
|
334
133
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
### SQS — return failed messageId values
|
|
338
|
-
|
|
339
|
-
```javascript
|
|
340
|
-
export const handler = async (event) => {
|
|
341
|
-
const batchItemFailures = [];
|
|
342
|
-
for (const record of event.Records) {
|
|
343
|
-
try {
|
|
344
|
-
await processMessage(record);
|
|
345
|
-
} catch (error) {
|
|
346
|
-
batchItemFailures.push({ itemIdentifier: record.messageId });
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
return { batchItemFailures };
|
|
350
|
-
};
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
### Streams — return failed SequenceNumber values
|
|
354
|
-
|
|
355
|
-
For DynamoDB Streams and Kinesis, Lambda uses the **lowest sequence number** as the checkpoint and retries everything from that point.
|
|
356
|
-
|
|
357
|
-
```javascript
|
|
358
|
-
export const handler = async (event) => {
|
|
359
|
-
for (const record of event.Records) {
|
|
360
|
-
try {
|
|
361
|
-
await processRecord(record);
|
|
362
|
-
} catch (e) {
|
|
363
|
-
return {
|
|
364
|
-
batchItemFailures: [
|
|
365
|
-
{ itemIdentifier: record.dynamodb.SequenceNumber },
|
|
366
|
-
// Kinesis: { itemIdentifier: record.kinesis.sequenceNumber }
|
|
367
|
-
],
|
|
368
|
-
};
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
return { batchItemFailures: [] };
|
|
372
|
-
};
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
### Python with Powertools Batch Processor
|
|
376
|
-
|
|
377
|
-
```python
|
|
378
|
-
from aws_lambda_powertools.utilities.batch import (
|
|
379
|
-
BatchProcessor, EventType, process_partial_response,
|
|
380
|
-
)
|
|
381
|
-
|
|
382
|
-
processor = BatchProcessor(event_type=EventType.SQS)
|
|
383
|
-
|
|
384
|
-
def record_handler(record):
|
|
385
|
-
payload = record.body
|
|
386
|
-
# process payload...
|
|
387
|
-
|
|
388
|
-
def lambda_handler(event, context):
|
|
389
|
-
return process_partial_response(
|
|
390
|
-
event=event, record_handler=record_handler,
|
|
391
|
-
processor=processor, context=context,
|
|
392
|
-
)
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
### FIFO queue behavior
|
|
396
|
-
|
|
397
|
-
- **Stop processing after the first failure**
|
|
398
|
-
- Return all failed and unprocessed messages in `batchItemFailures`
|
|
399
|
-
- This preserves message ordering within the group
|
|
134
|
+
Set `FunctionResponseTypes: [ReportBatchItemFailures]` and return the failed identifiers.
|
|
400
135
|
|
|
401
|
-
|
|
136
|
+
- **SQS:** return failed `messageId` values in `batchItemFailures`.
|
|
137
|
+
- **Streams (DynamoDB/Kinesis):** return the failed `SequenceNumber`; Lambda checkpoints at the **lowest** returned sequence number and retries everything from that point.
|
|
138
|
+
- **FIFO:** stop after the first failure; return that message plus all unprocessed ones (preserves ordering).
|
|
402
139
|
|
|
403
|
-
|
|
404
|
-
|----------|---------------|
|
|
405
|
-
| Empty `batchItemFailures` list | Complete success |
|
|
406
|
-
| Null `batchItemFailures` or empty `EventResponse` | Complete success |
|
|
407
|
-
| `itemIdentifier` is empty string or null | **Complete failure** (entire batch retried) |
|
|
408
|
-
| Bad key name in `itemIdentifier` | **Complete failure** |
|
|
409
|
-
| Unhandled exception | **Complete failure** |
|
|
140
|
+
Response edge cases that cause a **complete batch retry**: `itemIdentifier` empty/null, a bad key name, or any unhandled exception. An empty/null `batchItemFailures` = complete success.
|
|
410
141
|
|
|
411
|
-
|
|
142
|
+
Streams interaction: an unhandled **exception** triggers `BisectBatchOnFunctionError` (no response returned, so `ReportBatchItemFailures` has no effect); a **success with `batchItemFailures`** checkpoints at the lowest failed sequence number.
|
|
412
143
|
|
|
413
|
-
|
|
414
|
-
- Function **succeeds** with `batchItemFailures`: Lambda checkpoints at the lowest failed sequence number and retries from that point. If `BisectBatchOnFunctionError` is also enabled, the batch is bisected at the returned sequence number.
|
|
144
|
+
The Powertools Batch Processor (`process_partial_response`) handles all of this — prefer it over hand-rolled loops. See [assets/powertools-handler.py](../assets/powertools-handler.py).
|
|
415
145
|
|
|
416
146
|
---
|
|
417
147
|
|
|
418
|
-
## Error handling
|
|
419
|
-
|
|
420
|
-
### SQS
|
|
421
|
-
|
|
422
|
-
| Strategy | Configuration | When to use |
|
|
423
|
-
|----------|--------------|-------------|
|
|
424
|
-
| SQS redrive policy (DLQ) | `maxReceiveCount` on the queue | Always — catches poison messages |
|
|
425
|
-
| Partial batch failures | `ReportBatchItemFailures` | Batches with mix of good/bad messages |
|
|
426
|
-
| Visibility timeout | Set to ≥ 6× function timeout | Always — prevents premature retry |
|
|
427
|
-
| MaximumConcurrency | `ScalingConfig` on ESM | Protect downstream resources |
|
|
148
|
+
## Error handling and concurrency
|
|
428
149
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
|
432
|
-
|
|
433
|
-
| BisectBatchOnFunctionError | `true` | Isolate bad records in large batches |
|
|
434
|
-
| Partial batch failures | `ReportBatchItemFailures` | Avoid reprocessing successful records |
|
|
435
|
-
| Maximum retry attempts | `MaximumRetryAttempts` | Limit retries to prevent shard blocking |
|
|
436
|
-
| Maximum record age | `MaximumRecordAgeInSeconds` | Skip stale records |
|
|
437
|
-
| On-failure destination | `DestinationConfig.OnFailure` | Capture failed records for analysis |
|
|
438
|
-
| Parallelization factor | `ParallelizationFactor` | Reduce blast radius per shard |
|
|
439
|
-
|
|
440
|
-
### ESM (polling) vs direct trigger (push)
|
|
441
|
-
|
|
442
|
-
| Aspect | ESM (SQS, DDB, Kinesis) | Async push (SNS, S3) | Sync push (API Gateway) |
|
|
443
|
-
|--------|--------------------------|----------------------|-------------------------|
|
|
444
|
-
| Invocation | Synchronous (Lambda polls) | Asynchronous (service pushes) | Synchronous (service pushes) |
|
|
445
|
-
| Batching | Yes (configurable) | No (single event) | No (single event) |
|
|
446
|
-
| Event filtering | Lambda `FilterCriteria` | SNS filter policies (SNS-managed) | N/A |
|
|
447
|
-
| Error handling | Partial batch, bisect, retry config | 2 automatic retries, DLQ/destination | Error returned directly to caller, no automatic retry |
|
|
448
|
-
| Ordering | Supported (streams, FIFO) | Not guaranteed | N/A (request/response) |
|
|
150
|
+
| Source | Key strategies |
|
|
151
|
+
|--------|---------------|
|
|
152
|
+
| SQS | Redrive policy / DLQ (`maxReceiveCount`) always; `ReportBatchItemFailures`; visibility ≥ 6× timeout; `MaximumConcurrency` to protect downstream |
|
|
153
|
+
| DynamoDB/Kinesis | `BisectBatchOnFunctionError`; `ReportBatchItemFailures`; `MaximumRetryAttempts` + `MaximumRecordAgeInSeconds` (prevent shard blocking); `OnFailure` destination; `ParallelizationFactor` to reduce blast radius |
|
|
449
154
|
|
|
450
155
|
### Concurrency formulas
|
|
451
156
|
|
|
452
157
|
```
|
|
453
158
|
SQS (default): min(1250, MaximumConcurrency, ReservedConcurrency)
|
|
454
159
|
SQS (provisioned): MaximumPollers × 10
|
|
455
|
-
|
|
160
|
+
DynamoDB/Kinesis: number_of_shards × ParallelizationFactor
|
|
456
161
|
```
|
|
457
162
|
|
|
458
163
|
### Idempotency
|
|
459
164
|
|
|
460
|
-
All event sources deliver at
|
|
461
|
-
|
|
462
|
-
```python
|
|
463
|
-
from aws_lambda_powertools.utilities.batch import (
|
|
464
|
-
BatchProcessor, EventType, process_partial_response,
|
|
465
|
-
)
|
|
466
|
-
from aws_lambda_powertools.utilities.idempotency import (
|
|
467
|
-
IdempotencyConfig, DynamoDBPersistenceLayer, idempotent_function,
|
|
468
|
-
)
|
|
469
|
-
|
|
470
|
-
processor = BatchProcessor(event_type=EventType.SQS)
|
|
471
|
-
persistence_layer = DynamoDBPersistenceLayer(table_name="IdempotencyTable")
|
|
472
|
-
config = IdempotencyConfig(event_key_jmespath="messageId")
|
|
473
|
-
|
|
474
|
-
@idempotent_function(config=config, persistence_store=persistence_layer, data_keyword_argument="record")
|
|
475
|
-
def record_handler(record):
|
|
476
|
-
# process record...
|
|
477
|
-
pass
|
|
478
|
-
|
|
479
|
-
def lambda_handler(event, context):
|
|
480
|
-
return process_partial_response(
|
|
481
|
-
event=event, record_handler=record_handler,
|
|
482
|
-
processor=processor, context=context,
|
|
483
|
-
)
|
|
484
|
-
```
|
|
165
|
+
All event sources deliver at-least-once — duplicates happen. Make handlers idempotent (Powertools Idempotency utility, keyed e.g. on SQS `messageId`). See [production.md](production.md#idempotency).
|