mammoth 1.5.3 → 1.5.4
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +119 -33
- data/lib/mammoth/payload_policy.rb +10 -2
- data/lib/mammoth/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e8384a9b1f089aa255d05a7139f3af6acc6458ae83c9e6b16ad3c70b90354243
|
|
4
|
+
data.tar.gz: 57d7f1f4a4de5d3086900f11a60bfaaeab6269ede33dffab1bbbed49e8988648
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c96d457e14aeace5000dbdbe0614008447c9c0dd319c324d235db269fb25a53af573a2b87f4f4c9c0bcd39127975cc919730cb08b632e96972271c8459216a22
|
|
7
|
+
data.tar.gz: 0cbf023b425053a16d74ad5198377b9a4dc11988a85920888c2a8e7bdc83d2986bfc212b703715a2297bb3035d2792916810684d935d7728a01385f022c0b095
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,13 @@
|
|
|
6
6
|
|
|
7
7
|
## Unreleased
|
|
8
8
|
|
|
9
|
+
## 1.5.4 - 2026-08-26
|
|
10
|
+
|
|
11
|
+
- Upgraded runtime depency sqlite3 from 2.9.5 to 2.9.6 because of security/stability reasons
|
|
12
|
+
as outline by this PR https://github.com/kanutocd/mammoth/pull/21 by @dependabot
|
|
13
|
+
- Fixed the Dockerfile security issue that was flagged by Trivy by unpinning the ruby base image's digest hash
|
|
14
|
+
and explicitly include an `apt-get upgrade`
|
|
15
|
+
|
|
9
16
|
## 1.5.3 - 2026-07-26
|
|
10
17
|
|
|
11
18
|
### Fixed
|
data/README.md
CHANGED
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
[](https://github.com/kanutocd/mammoth/blob/main/.github/workflows/ci.yml#L50)
|
|
22
22
|
[](LICENSE.txt)
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
Mammoth is a self-hosted PostgreSQL change-event relay focused on reliable
|
|
25
|
+
delivery of database change events to downstream systems. It turns PostgreSQL
|
|
26
|
+
logical replication streams into observable, recoverable delivery pipelines.
|
|
27
27
|
|
|
28
28
|
This repository contains the **Mammoth Data Plane**, the open-source runtime in
|
|
29
29
|
the broader Mammoth ecosystem:
|
|
@@ -52,6 +52,50 @@ Mammoth is intentionally boring infrastructure. It uses YAML configuration,
|
|
|
52
52
|
JSON Schema validation, local SQLite operational state, and the CDC Ecosystem's
|
|
53
53
|
shared vocabulary so operators can inspect, recover, and reason about delivery.
|
|
54
54
|
|
|
55
|
+
## Why Mammoth?
|
|
56
|
+
|
|
57
|
+
Mammoth is designed for applications where PostgreSQL is the system of record,
|
|
58
|
+
including Rails applications that need reliable reactions to database state
|
|
59
|
+
changes without coupling every workflow to request handling.
|
|
60
|
+
|
|
61
|
+
Applications increasingly need to react to changes in their primary database:
|
|
62
|
+
|
|
63
|
+
- update search indexes after data changes
|
|
64
|
+
- synchronize external systems
|
|
65
|
+
- trigger integrations and asynchronous workflows
|
|
66
|
+
- build analytics pipelines
|
|
67
|
+
- maintain audit and event histories
|
|
68
|
+
|
|
69
|
+
Many systems start with polling, application callbacks, or database triggers.
|
|
70
|
+
As applications grow, these approaches can become increasingly difficult to
|
|
71
|
+
operate, recover from failures, and reason about.
|
|
72
|
+
|
|
73
|
+
Mammoth uses PostgreSQL logical replication as the authoritative change stream
|
|
74
|
+
and provides a reliable delivery layer between PostgreSQL and downstream
|
|
75
|
+
consumers.
|
|
76
|
+
|
|
77
|
+
The goal is simple: make database change delivery explicit, observable, and
|
|
78
|
+
recoverable.
|
|
79
|
+
|
|
80
|
+
## What makes Mammoth different?
|
|
81
|
+
|
|
82
|
+
Mammoth deliberately focuses on the delivery boundary between PostgreSQL and
|
|
83
|
+
downstream consumers rather than trying to become a general-purpose streaming
|
|
84
|
+
platform.
|
|
85
|
+
|
|
86
|
+
It treats change delivery as an operational concern:
|
|
87
|
+
|
|
88
|
+
- transactional change-event handling
|
|
89
|
+
- durable delivery state
|
|
90
|
+
- explicit checkpoint management
|
|
91
|
+
- replayable failures
|
|
92
|
+
- observable runtime behavior
|
|
93
|
+
|
|
94
|
+
Unlike application callbacks, Mammoth does not require workflows to execute
|
|
95
|
+
inside request handling. Unlike broad streaming platforms, it provides a
|
|
96
|
+
focused PostgreSQL-native model for teams that need reliable change delivery
|
|
97
|
+
without adopting a larger streaming infrastructure stack.
|
|
98
|
+
|
|
55
99
|
## Mammoth ecosystem
|
|
56
100
|
|
|
57
101
|
The Data Plane is one component of the broader Mammoth ecosystem. The companion
|
|
@@ -62,17 +106,56 @@ See the [Mammoth ecosystem overview](docs/ECOSYSTEM.md) for public scope,
|
|
|
62
106
|
integration boundaries, and roadmap status. Planned capabilities are
|
|
63
107
|
directional and do not represent a release commitment.
|
|
64
108
|
|
|
109
|
+
## Reference Implementation
|
|
110
|
+
|
|
111
|
+
The [Spherical Mammoth](https://github.com/kanutocd/spherical-mammoth)
|
|
112
|
+
repository is the production-shaped, cloud-native reference environment for
|
|
113
|
+
deploying, validating, and operating the Mammoth Data Plane.
|
|
114
|
+
|
|
115
|
+
It demonstrates how Mammoth integrates into a complete application environment:
|
|
116
|
+
|
|
117
|
+
```text
|
|
118
|
+
Application services
|
|
119
|
+
↓
|
|
120
|
+
PostgreSQL transactional state
|
|
121
|
+
↓
|
|
122
|
+
PostgreSQL logical replication
|
|
123
|
+
↓
|
|
124
|
+
Mammoth Data Plane
|
|
125
|
+
↓
|
|
126
|
+
Webhook delivery
|
|
127
|
+
↓
|
|
128
|
+
Independent downstream consumers
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Spherical Mammoth provides:**
|
|
132
|
+
|
|
133
|
+
- a realistic SaaS-style application workflow
|
|
134
|
+
- PostgreSQL-backed business state
|
|
135
|
+
- Ory Kratos identity lifecycle integration
|
|
136
|
+
- polyglot downstream consumers
|
|
137
|
+
- Docker Compose and Kubernetes deployment paths
|
|
138
|
+
- Helm-based deployment
|
|
139
|
+
- OpenTofu-managed cloud infrastructure examples
|
|
140
|
+
- CDC validation and failure scenarios
|
|
141
|
+
|
|
142
|
+
The repository is intentionally separate from Mammoth OSS. Mammoth provides the
|
|
143
|
+
CDC relay data plane; Spherical Mammoth demonstrates how that data plane can be
|
|
144
|
+
deployed, exercised, and operated in a cloud-native environment.
|
|
145
|
+
|
|
146
|
+
See:
|
|
147
|
+
|
|
148
|
+
- [Spherical Mammoth](https://github.com/kanutocd/spherical-mammoth)
|
|
149
|
+
- [Cloud-native deployment guide](https://github.com/kanutocd/spherical-mammoth/blob/main/docs/runbooks/cloud-native-mammoth.md)
|
|
150
|
+
|
|
151
|
+
|
|
65
152
|
## Supported PostgreSQL versions
|
|
66
153
|
|
|
67
|
-
Mammoth supports PostgreSQL 14 through PostgreSQL 18, inclusive. These are the
|
|
68
|
-
PostgreSQL major versions currently maintained by the PostgreSQL community and
|
|
69
|
-
covered by Mammoth's real logical-replication E2E compatibility matrix.
|
|
154
|
+
Mammoth supports PostgreSQL 14 through PostgreSQL 18, inclusive. These versions are currently maintained by the PostgreSQL community and covered by Mammoth's logical-replication E2E compatibility matrix.
|
|
70
155
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
versions may be removed from the supported range in a subsequent Mammoth minor
|
|
75
|
-
release with release-note notice.
|
|
156
|
+
New PostgreSQL majors are unsupported until explicitly tested and documented.
|
|
157
|
+
EOL versions may be removed from the supported range in a subsequent Mammoth
|
|
158
|
+
minor release with release-note notice.
|
|
76
159
|
|
|
77
160
|
PostgreSQL 19 is a development release and is not supported.
|
|
78
161
|
|
|
@@ -120,7 +203,7 @@ Mammoth 1.x includes:
|
|
|
120
203
|
- JSON Schema-backed configuration validation
|
|
121
204
|
- SQLite operational memory bootstrap
|
|
122
205
|
- checkpoint persistence
|
|
123
|
-
- dead
|
|
206
|
+
- dead-letter persistence
|
|
124
207
|
- delivered-envelope ledger persistence
|
|
125
208
|
- webhook delivery sink
|
|
126
209
|
- webhook fanout to multiple destinations
|
|
@@ -163,7 +246,7 @@ modes, not isolated API snippets.
|
|
|
163
246
|
| [`schema_evolution`](examples/schema_evolution) | Consumer-first additive schema evolution without implying DDL delivery. |
|
|
164
247
|
| [`destination_idempotency`](examples/destination_idempotency) | Atomic destination-side duplicate suppression across isolated relay ledgers. |
|
|
165
248
|
| [`failing_webhook_retry`](examples/failing_webhook_retry) | Retry exhaustion and durable dead-letter persistence. |
|
|
166
|
-
| [`operational_state`](examples/operational_state) | Inspectable checkpoints, delivered ledgers, and dead
|
|
249
|
+
| [`operational_state`](examples/operational_state) | Inspectable checkpoints, delivered ledgers, and dead-letters. |
|
|
167
250
|
| [`kubernetes_helm`](examples/kubernetes_helm) | Single-consumer Kubernetes deployment using the public Helm chart. |
|
|
168
251
|
|
|
169
252
|
See [`examples/README.md`](examples/README.md) for the complete index, boundary
|
|
@@ -186,36 +269,40 @@ and transaction JSON contracts, column-change semantics, and event-ID behavior.
|
|
|
186
269
|
|
|
187
270
|
## Boundary
|
|
188
271
|
|
|
189
|
-
Mammoth begins at CDC
|
|
272
|
+
Mammoth begins at CDC Core work items and ends at webhook fanout delivery.
|
|
190
273
|
|
|
191
274
|
Mammoth does not own pgoutput protocol parsing, value decoding, source
|
|
192
|
-
normalization, or core dispatch vocabulary. Those belong to
|
|
193
|
-
Ecosystem components. Mammoth selects and composes a delivery
|
|
194
|
-
delegating
|
|
195
|
-
wraps the selected adapter with configured batch accumulation;
|
|
196
|
-
only streams core work and coordinates lifecycle flush and
|
|
275
|
+
normalization, or core dispatch vocabulary. Those responsibilities belong to
|
|
276
|
+
upstream CDC Ecosystem components. Mammoth selects and composes a delivery
|
|
277
|
+
runtime while delegating scheduling mechanics to the runtime layer.
|
|
278
|
+
The runtime registry wraps the selected adapter with configured batch accumulation;
|
|
279
|
+
`Application` only streams core work and coordinates lifecycle flush and
|
|
280
|
+
shutdown calls.
|
|
197
281
|
|
|
198
282
|
For the live PostgreSQL stream, `pgoutput-source-adapter` incrementally owns
|
|
199
283
|
`Begin`/`Commit` buffering and emits exact `CDC::Core::ChangeEvent` or
|
|
200
284
|
`CDC::Core::TransactionEnvelope` work items. Mammoth only composes the
|
|
201
|
-
transport, parser, decoder, and source adapter
|
|
202
|
-
work to delivery. Mammoth's publication preflight supplies ordered,
|
|
285
|
+
transport, parser, decoder, and source adapter, then forwards the resulting
|
|
286
|
+
core work to delivery. Mammoth's publication preflight supplies ordered,
|
|
203
287
|
catalog-derived replica-identity columns to the adapter, which owns composite
|
|
204
288
|
and non-`id` key extraction.
|
|
205
289
|
|
|
206
290
|
At the downstream boundary, `Mammoth::DeliveryProcessor` implements
|
|
207
291
|
`CDC::Core::Processor` and returns `CDC::Core::ProcessorResult`. Inline and
|
|
208
292
|
concurrent runtimes notify a `CDC::Core::Observer`; Mammoth's default observer
|
|
209
|
-
maps
|
|
293
|
+
maps canonical started, succeeded, failed, and skipped notifications to
|
|
210
294
|
Prometheus counters.
|
|
211
295
|
|
|
212
|
-
`Mammoth::ReplicationConsumer` accepts only
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
296
|
+
`Mammoth::ReplicationConsumer` accepts only CDC Core event and transaction
|
|
297
|
+
envelope types.
|
|
298
|
+
|
|
299
|
+
`deliver-sample` input passes through `PersistedPayloadDeserializer` before
|
|
300
|
+
entering the live delivery path, ensuring stored hashes do not masquerade as
|
|
301
|
+
CDC Core work.
|
|
302
|
+
|
|
303
|
+
Dead-letter replay is a separate destination boundary: Mammoth sends the exact
|
|
304
|
+
prepared JSON persisted for that destination and does not reconstruct CDC work
|
|
305
|
+
or reapply the current payload policy.
|
|
219
306
|
|
|
220
307
|
## Extensions
|
|
221
308
|
|
|
@@ -341,10 +428,9 @@ A reference benchmark run on Ruby 4.0.5 produced:
|
|
|
341
428
|
| SQLite delivered-ledger writes | **1,630 writes/sec** |
|
|
342
429
|
| Dead-letter replay mechanics | **1,030 entries/sec** |
|
|
343
430
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
I/O-bound downstream delivery.
|
|
431
|
+
Mammoth processed **1,862 transactions/sec** against a calculated workload
|
|
432
|
+
ceiling of 2,000 transactions/sec, while maintaining **28.4 ms P95 latency**.
|
|
433
|
+
This indicates low scheduling overhead for I/O-bound downstream delivery.
|
|
348
434
|
|
|
349
435
|
These are local, single-trial reference measurements, not universal capacity
|
|
350
436
|
claims or comparisons with other CDC platforms. The benchmarks isolate specific
|
|
@@ -135,14 +135,22 @@ module Mammoth
|
|
|
135
135
|
return value.map { |item| canonicalize(item) } if value.is_a?(Array)
|
|
136
136
|
return value unless value.is_a?(Hash)
|
|
137
137
|
|
|
138
|
-
value.keys.sort.
|
|
138
|
+
value.keys.sort.each_with_object(
|
|
139
|
+
{} # : Hash[untyped, untyped]
|
|
140
|
+
) do |key, result|
|
|
141
|
+
result[key] = canonicalize(value.fetch(key))
|
|
142
|
+
end
|
|
139
143
|
end
|
|
140
144
|
|
|
141
145
|
def stringify_keys(value)
|
|
142
146
|
return value.map { |item| stringify_keys(item) } if value.is_a?(Array)
|
|
143
147
|
return value unless value.is_a?(Hash)
|
|
144
148
|
|
|
145
|
-
value.
|
|
149
|
+
value.each_with_object(
|
|
150
|
+
{} # : Hash[String, untyped]
|
|
151
|
+
) do |(key, item), result|
|
|
152
|
+
result[key.to_s] = stringify_keys(item)
|
|
153
|
+
end
|
|
146
154
|
end
|
|
147
155
|
|
|
148
156
|
def deep_freeze(value)
|
data/lib/mammoth/version.rb
CHANGED