mammoth 0.6.0 → 0.7.1
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 +27 -1
- data/README.md +16 -0
- data/config/mammoth.example.yml +17 -0
- data/config/mammoth.schema.json +56 -1
- data/lib/mammoth/application.rb +58 -23
- data/lib/mammoth/capabilities.rb +59 -0
- data/lib/mammoth/cdc_source.rb +1 -1
- data/lib/mammoth/cli.rb +16 -24
- data/lib/mammoth/commands/bootstrap_command.rb +26 -0
- data/lib/mammoth/commands/dead_letters_command.rb +22 -0
- data/lib/mammoth/commands/deliver_sample_command.rb +35 -0
- data/lib/mammoth/commands/start_command.rb +28 -0
- data/lib/mammoth/commands/status_command.rb +28 -0
- data/lib/mammoth/commands/validate_command.rb +24 -0
- data/lib/mammoth/configuration.rb +66 -7
- data/lib/mammoth/dead_letter_commands.rb +17 -9
- data/lib/mammoth/dead_letter_store.rb +4 -0
- data/lib/mammoth/delivered_envelope_store.rb +3 -0
- data/lib/mammoth/destinations/adapter.rb +20 -0
- data/lib/mammoth/destinations/registry.rb +46 -0
- data/lib/mammoth/destinations/webhook_adapter.rb +29 -0
- data/lib/mammoth/lifecycle_hooks.rb +56 -0
- data/lib/mammoth/node_identity.rb +54 -0
- data/lib/mammoth/observability_server.rb +2 -0
- data/lib/mammoth/operational_state/adapter.rb +37 -0
- data/lib/mammoth/operational_state/registry.rb +46 -0
- data/lib/mammoth/operational_state/sqlite_adapter.rb +44 -0
- data/lib/mammoth/registry.rb +46 -0
- data/lib/mammoth/runtimes/adapter.rb +23 -0
- data/lib/mammoth/runtimes/concurrent_adapter.rb +31 -0
- data/lib/mammoth/runtimes/inline_adapter.rb +40 -0
- data/lib/mammoth/runtimes/registry.rb +46 -0
- data/lib/mammoth/status.rb +55 -13
- data/lib/mammoth/version.rb +1 -1
- data/lib/mammoth.rb +28 -3
- metadata +21 -1
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mammoth
|
|
4
|
+
module Runtimes
|
|
5
|
+
# Inline runtime adapter that processes work in the caller thread.
|
|
6
|
+
class InlineAdapter < Adapter
|
|
7
|
+
attr_reader :processor
|
|
8
|
+
|
|
9
|
+
# @param processor [#process] delivery processor
|
|
10
|
+
def initialize(processor:)
|
|
11
|
+
super()
|
|
12
|
+
@processor = processor
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Build an inline runtime.
|
|
16
|
+
#
|
|
17
|
+
# @param processor [#process] delivery processor
|
|
18
|
+
# @return [Mammoth::Runtimes::InlineAdapter]
|
|
19
|
+
def self.build(processor:, **_options)
|
|
20
|
+
new(processor: processor)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# @return [String] adapter type name
|
|
24
|
+
def self.adapter_type
|
|
25
|
+
"inline"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @param items [Array<Object>] work units
|
|
29
|
+
# @return [Array<Object>] processor results
|
|
30
|
+
def process_many(items)
|
|
31
|
+
items.map { |item| processor.process(item) }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @return [nil]
|
|
35
|
+
def shutdown
|
|
36
|
+
nil
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mammoth
|
|
4
|
+
module Runtimes
|
|
5
|
+
# Registry for delivery runtime adapters.
|
|
6
|
+
module Registry
|
|
7
|
+
class << self
|
|
8
|
+
# Register a runtime adapter.
|
|
9
|
+
#
|
|
10
|
+
# @param name [String, Symbol] adapter name
|
|
11
|
+
# @param adapter [Object] adapter class
|
|
12
|
+
# @return [Object] registered adapter
|
|
13
|
+
def register(name, adapter)
|
|
14
|
+
registry.register(name, adapter)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Fetch a runtime adapter.
|
|
18
|
+
#
|
|
19
|
+
# @param name [String, Symbol] adapter name
|
|
20
|
+
# @return [Object] adapter class
|
|
21
|
+
def fetch(name)
|
|
22
|
+
registry.fetch(name)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Build a runtime adapter.
|
|
26
|
+
#
|
|
27
|
+
# @param name [String, Symbol] adapter name
|
|
28
|
+
# @param options [Hash] adapter-specific build options
|
|
29
|
+
# @return [Object] runtime adapter
|
|
30
|
+
def build(name, **options)
|
|
31
|
+
fetch(name).build(**options)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @return [Array<String>] registered runtime adapter names
|
|
35
|
+
def names
|
|
36
|
+
registry.names
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @return [Mammoth::Registry] underlying registry
|
|
40
|
+
def registry
|
|
41
|
+
@registry ||= Mammoth::Registry.new("runtime")
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
data/lib/mammoth/status.rb
CHANGED
|
@@ -3,39 +3,73 @@
|
|
|
3
3
|
module Mammoth
|
|
4
4
|
# Builds and prints a boring operational status snapshot.
|
|
5
5
|
class Status
|
|
6
|
-
attr_reader :config, :sqlite_store
|
|
6
|
+
attr_reader :config, :sqlite_store, :output
|
|
7
7
|
|
|
8
8
|
# Print status for a configuration and optional SQLite store.
|
|
9
9
|
#
|
|
10
10
|
# @param config [Mammoth::Configuration] loaded configuration
|
|
11
11
|
# @param sqlite_store [Mammoth::SQLiteStore, nil] operational store
|
|
12
12
|
# @return [void]
|
|
13
|
-
def self.call(config, sqlite_store: nil)
|
|
14
|
-
new(config, sqlite_store: sqlite_store).call
|
|
13
|
+
def self.call(config, sqlite_store: nil, output: $stdout)
|
|
14
|
+
new(config, sqlite_store: sqlite_store, output: output).call
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
# @param config [Mammoth::Configuration] loaded configuration
|
|
18
18
|
# @param sqlite_store [Mammoth::SQLiteStore, nil] operational store
|
|
19
|
-
|
|
19
|
+
# @param output [#puts] output stream
|
|
20
|
+
def initialize(config, sqlite_store: nil, output: $stdout)
|
|
20
21
|
@config = config
|
|
21
22
|
@sqlite_store = sqlite_store
|
|
23
|
+
@output = output
|
|
22
24
|
end
|
|
23
25
|
|
|
24
26
|
# Print the status snapshot.
|
|
25
27
|
#
|
|
26
28
|
# @return [void]
|
|
27
29
|
def call
|
|
28
|
-
|
|
29
|
-
puts "Replication slot: #{config.dig("replication", "slot")}"
|
|
30
|
-
puts "Replication publications: #{Array(config.dig("replication", "publications")).join(", ")}"
|
|
31
|
-
puts "Runtime: not started"
|
|
32
|
-
puts "SQLite: #{sqlite_path}"
|
|
33
|
-
puts "Destinations: #{destination_names.join(", ")}"
|
|
30
|
+
status_lines.each { |line| output.puts(line) }
|
|
34
31
|
print_store_state if sqlite_store
|
|
35
32
|
end
|
|
36
33
|
|
|
37
34
|
private
|
|
38
35
|
|
|
36
|
+
def status_lines
|
|
37
|
+
identity_lines + replication_lines + runtime_lines + destination_lines + ["SQLite: #{sqlite_path}"]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def identity_lines
|
|
41
|
+
[
|
|
42
|
+
"Mammoth: #{config.dig("mammoth", "name")}",
|
|
43
|
+
"Node ID: #{node_identity.node_id}",
|
|
44
|
+
"Node name: #{node_identity.node_name}",
|
|
45
|
+
"Fleet: #{node_identity.fleet_id || "unassigned"}",
|
|
46
|
+
"Environment: #{node_identity.environment || "unspecified"}"
|
|
47
|
+
]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def replication_lines
|
|
51
|
+
[
|
|
52
|
+
"Replication slot: #{config.dig("replication", "slot")}",
|
|
53
|
+
"Replication publications: #{Array(config.dig("replication", "publications")).join(", ")}"
|
|
54
|
+
]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def runtime_lines
|
|
58
|
+
[
|
|
59
|
+
"Runtime: not started",
|
|
60
|
+
"Runtime adapter: #{capabilities.fetch(:runtime)}",
|
|
61
|
+
"Operational state: #{capabilities.fetch(:operational_state)}"
|
|
62
|
+
]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def destination_lines
|
|
66
|
+
[
|
|
67
|
+
"Destinations: #{destination_names.join(", ")}",
|
|
68
|
+
"Destination adapters: #{capabilities.fetch(:destinations).join(", ")}",
|
|
69
|
+
"Features: #{capabilities.fetch(:features).join(", ")}"
|
|
70
|
+
]
|
|
71
|
+
end
|
|
72
|
+
|
|
39
73
|
def sqlite_path
|
|
40
74
|
config.dig("sqlite", "path")
|
|
41
75
|
end
|
|
@@ -47,11 +81,19 @@ module Mammoth
|
|
|
47
81
|
[config.dig("webhook", "name")]
|
|
48
82
|
end
|
|
49
83
|
|
|
84
|
+
def node_identity
|
|
85
|
+
@node_identity ||= NodeIdentity.from_config(config)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def capabilities
|
|
89
|
+
@capabilities ||= Capabilities.call(config)
|
|
90
|
+
end
|
|
91
|
+
|
|
50
92
|
def print_store_state
|
|
51
93
|
store = sqlite_store.bootstrap!
|
|
52
|
-
puts "Tables: #{store.tables.join(", ")}"
|
|
53
|
-
puts "Checkpoints: #{CheckpointStore.new(store).count}"
|
|
54
|
-
puts "Dead Letters: #{DeadLetterStore.new(store).count}"
|
|
94
|
+
output.puts "Tables: #{store.tables.join(", ")}"
|
|
95
|
+
output.puts "Checkpoints: #{CheckpointStore.new(store).count}"
|
|
96
|
+
output.puts "Dead Letters: #{DeadLetterStore.new(store).count}"
|
|
55
97
|
end
|
|
56
98
|
end
|
|
57
99
|
end
|
data/lib/mammoth/version.rb
CHANGED
data/lib/mammoth.rb
CHANGED
|
@@ -2,8 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative "mammoth/version"
|
|
4
4
|
require_relative "mammoth/errors"
|
|
5
|
+
require_relative "mammoth/registry"
|
|
5
6
|
require_relative "mammoth/configuration"
|
|
7
|
+
require_relative "mammoth/lifecycle_hooks"
|
|
8
|
+
require_relative "mammoth/node_identity"
|
|
9
|
+
require_relative "mammoth/capabilities"
|
|
6
10
|
require_relative "mammoth/status"
|
|
11
|
+
require_relative "mammoth/commands/validate_command"
|
|
12
|
+
require_relative "mammoth/commands/bootstrap_command"
|
|
13
|
+
require_relative "mammoth/commands/status_command"
|
|
14
|
+
require_relative "mammoth/commands/start_command"
|
|
15
|
+
require_relative "mammoth/commands/deliver_sample_command"
|
|
16
|
+
require_relative "mammoth/commands/dead_letters_command"
|
|
7
17
|
require_relative "mammoth/observability_snapshot"
|
|
8
18
|
require_relative "mammoth/observability_server"
|
|
9
19
|
require_relative "mammoth/sqlite_store"
|
|
@@ -14,10 +24,20 @@ require_relative "mammoth/event_serializer"
|
|
|
14
24
|
require_relative "mammoth/transaction_envelope_serializer"
|
|
15
25
|
require_relative "mammoth/route_filter"
|
|
16
26
|
require_relative "mammoth/webhook_sink"
|
|
27
|
+
require_relative "mammoth/operational_state/adapter"
|
|
28
|
+
require_relative "mammoth/operational_state/sqlite_adapter"
|
|
29
|
+
require_relative "mammoth/operational_state/registry"
|
|
30
|
+
require_relative "mammoth/destinations/adapter"
|
|
31
|
+
require_relative "mammoth/destinations/webhook_adapter"
|
|
32
|
+
require_relative "mammoth/destinations/registry"
|
|
17
33
|
require_relative "mammoth/delivery_worker"
|
|
18
34
|
require_relative "mammoth/fanout_delivery_worker"
|
|
19
35
|
require_relative "mammoth/delivery_processor"
|
|
20
36
|
require_relative "mammoth/concurrent_delivery_runtime"
|
|
37
|
+
require_relative "mammoth/runtimes/adapter"
|
|
38
|
+
require_relative "mammoth/runtimes/inline_adapter"
|
|
39
|
+
require_relative "mammoth/runtimes/concurrent_adapter"
|
|
40
|
+
require_relative "mammoth/runtimes/registry"
|
|
21
41
|
require_relative "mammoth/sources/postgres"
|
|
22
42
|
require_relative "mammoth/cdc_source"
|
|
23
43
|
require_relative "mammoth/replication_consumer"
|
|
@@ -27,8 +47,13 @@ require_relative "mammoth/cli"
|
|
|
27
47
|
|
|
28
48
|
# Mammoth is a self-hosted PostgreSQL event relay.
|
|
29
49
|
#
|
|
30
|
-
# Mammoth
|
|
31
|
-
#
|
|
32
|
-
# state,
|
|
50
|
+
# Mammoth 0.7.x is a single-node PostgreSQL CDC relay with webhook fanout,
|
|
51
|
+
# replayable operational SQLite state, health/metrics endpoints, and explicit
|
|
52
|
+
# extension contracts for state, destination, runtime, lifecycle, configuration,
|
|
53
|
+
# and local command integrations.
|
|
33
54
|
module Mammoth
|
|
55
|
+
OperationalState::Registry.register("sqlite", OperationalState::SQLiteAdapter)
|
|
56
|
+
Destinations::Registry.register("webhook", Destinations::WebhookAdapter)
|
|
57
|
+
Runtimes::Registry.register("inline", Runtimes::InlineAdapter)
|
|
58
|
+
Runtimes::Registry.register("concurrent", Runtimes::ConcurrentAdapter)
|
|
34
59
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mammoth
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ken C. Demanawa
|
|
@@ -145,9 +145,16 @@ files:
|
|
|
145
145
|
- exe/mammoth
|
|
146
146
|
- lib/mammoth.rb
|
|
147
147
|
- lib/mammoth/application.rb
|
|
148
|
+
- lib/mammoth/capabilities.rb
|
|
148
149
|
- lib/mammoth/cdc_source.rb
|
|
149
150
|
- lib/mammoth/checkpoint_store.rb
|
|
150
151
|
- lib/mammoth/cli.rb
|
|
152
|
+
- lib/mammoth/commands/bootstrap_command.rb
|
|
153
|
+
- lib/mammoth/commands/dead_letters_command.rb
|
|
154
|
+
- lib/mammoth/commands/deliver_sample_command.rb
|
|
155
|
+
- lib/mammoth/commands/start_command.rb
|
|
156
|
+
- lib/mammoth/commands/status_command.rb
|
|
157
|
+
- lib/mammoth/commands/validate_command.rb
|
|
151
158
|
- lib/mammoth/concurrent_delivery_runtime.rb
|
|
152
159
|
- lib/mammoth/configuration.rb
|
|
153
160
|
- lib/mammoth/dead_letter_commands.rb
|
|
@@ -155,13 +162,26 @@ files:
|
|
|
155
162
|
- lib/mammoth/delivered_envelope_store.rb
|
|
156
163
|
- lib/mammoth/delivery_processor.rb
|
|
157
164
|
- lib/mammoth/delivery_worker.rb
|
|
165
|
+
- lib/mammoth/destinations/adapter.rb
|
|
166
|
+
- lib/mammoth/destinations/registry.rb
|
|
167
|
+
- lib/mammoth/destinations/webhook_adapter.rb
|
|
158
168
|
- lib/mammoth/errors.rb
|
|
159
169
|
- lib/mammoth/event_serializer.rb
|
|
160
170
|
- lib/mammoth/fanout_delivery_worker.rb
|
|
171
|
+
- lib/mammoth/lifecycle_hooks.rb
|
|
172
|
+
- lib/mammoth/node_identity.rb
|
|
161
173
|
- lib/mammoth/observability_server.rb
|
|
162
174
|
- lib/mammoth/observability_snapshot.rb
|
|
175
|
+
- lib/mammoth/operational_state/adapter.rb
|
|
176
|
+
- lib/mammoth/operational_state/registry.rb
|
|
177
|
+
- lib/mammoth/operational_state/sqlite_adapter.rb
|
|
178
|
+
- lib/mammoth/registry.rb
|
|
163
179
|
- lib/mammoth/replication_consumer.rb
|
|
164
180
|
- lib/mammoth/route_filter.rb
|
|
181
|
+
- lib/mammoth/runtimes/adapter.rb
|
|
182
|
+
- lib/mammoth/runtimes/concurrent_adapter.rb
|
|
183
|
+
- lib/mammoth/runtimes/inline_adapter.rb
|
|
184
|
+
- lib/mammoth/runtimes/registry.rb
|
|
165
185
|
- lib/mammoth/sources/postgres.rb
|
|
166
186
|
- lib/mammoth/sql/__bootstrap__.sql
|
|
167
187
|
- lib/mammoth/sqlite_store.rb
|