wal 0.0.33 → 0.0.34
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/lib/wal/logging_watcher.rb +15 -10
- data/lib/wal/runner.rb +18 -10
- data/lib/wal/version.rb +1 -1
- data/lib/wal.rb +13 -5
- data/rbi/wal.rbi +12 -3
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f7a8f82addc9ffce03d2f1ee6a77bac1f3ae2074a5b427a8c60ca087df2aded6
|
|
4
|
+
data.tar.gz: 75559dccba1edf1d0f1a60ebf866726705fe48166d697a1859ec6da644e963f3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0d0d206e647386006b07e1a89e1a5596346a50894d0260d5def25876902abcbd398c07889a03ac43c88041343e576b2793eec8a1eecdcf47ff1f025587721a38
|
|
7
|
+
data.tar.gz: 62b2dbbeadf2c8076f2dee4ad1a95491552dfb0be3af646b03ffa449dd54009cfd940020fe4dfe3b69c2c5e7a707bdafdc2959baebe109ba28d288b31a086031
|
data/lib/wal/logging_watcher.rb
CHANGED
|
@@ -20,17 +20,18 @@ module Wal
|
|
|
20
20
|
def on_event(event)
|
|
21
21
|
case event
|
|
22
22
|
when Wal::BeginTransactionEvent
|
|
23
|
-
@start =
|
|
23
|
+
@start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
24
24
|
@count = 0
|
|
25
|
-
|
|
26
|
-
Wal.logger&.debug("[#{@slot}] Begin transaction=#{event.transaction_id} size=#{event.estimated_size}")
|
|
27
|
-
end
|
|
25
|
+
Wal.logger&.debug("[#{@slot}] Begin transaction=#{event.transaction_id} size=#{event.estimated_size}")
|
|
28
26
|
when Wal::CommitTransactionEvent
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
elapsed = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - @start) * 1000).round(3)
|
|
28
|
+
message = "[#{@slot}] Commit transaction=#{event.transaction_id} elapsed=#{elapsed} events=#{@count}"
|
|
29
|
+
message << " actions=#{@actions.sort.join(",")}" unless @actions.empty?
|
|
30
|
+
message << " tables=#{@tables.sort.join(",")}" unless @tables.empty?
|
|
31
|
+
if @count > 1
|
|
32
|
+
Wal.logger&.info(message)
|
|
33
|
+
else
|
|
34
|
+
Wal.logger&.debug(message)
|
|
34
35
|
end
|
|
35
36
|
@actions.clear
|
|
36
37
|
@tables.clear
|
|
@@ -40,7 +41,11 @@ module Wal
|
|
|
40
41
|
@actions << :insert
|
|
41
42
|
@tables << event.table
|
|
42
43
|
when Wal::UpdateEvent
|
|
43
|
-
Wal.logger&.
|
|
44
|
+
if Wal.logger&.level >= Logger::DEBUG
|
|
45
|
+
message = "[#{@slot}] Update transaction=#{event.transaction_id} table=#{event.table} primary_key=#{event.primary_key}"
|
|
46
|
+
message << " changed=#{event.diff.keys.join(",")}" if event.diff && !event.diff.empty?
|
|
47
|
+
Wal.logger&.debug(message)
|
|
48
|
+
end
|
|
44
49
|
@count += 1
|
|
45
50
|
@actions << :update
|
|
46
51
|
@tables << event.table
|
data/lib/wal/runner.rb
CHANGED
|
@@ -32,30 +32,38 @@ module Wal
|
|
|
32
32
|
Thread.new(slot, watcher, temporary, publications) do |replication_slot, watcher, use_temporary_slot, publications|
|
|
33
33
|
retries = 0
|
|
34
34
|
replication_slot = "#{replication_slot}_#{SecureRandom.alphanumeric(4)}" if use_temporary_slot
|
|
35
|
-
puts "Watcher started for #{replication_slot} slot (#{publications.join(", ")})"
|
|
35
|
+
puts "[#{replication_slot}] Watcher started for #{replication_slot} slot (#{publications.join(", ")})"
|
|
36
36
|
|
|
37
37
|
begin
|
|
38
|
+
Wal.hooks[:on_slot_start]&.call(slot, config)
|
|
39
|
+
|
|
38
40
|
replicator_class
|
|
39
41
|
.new(db_config:, **replicator_params, replication_slot:, use_temporary_slot:)
|
|
40
42
|
.replicate_forever(Wal::LoggingWatcher.new(replication_slot, watcher), publications:)
|
|
43
|
+
|
|
44
|
+
Wal.hooks[:on_slot_finish]&.call(slot, config)
|
|
45
|
+
|
|
41
46
|
if auto_restart
|
|
42
47
|
backoff_time = backoff_exponent ? (backoff * retries) ** backoff_exponent : backoff
|
|
43
|
-
puts "Watcher finished for #{replication_slot}, auto restarting in #{backoff_time.floor(2)}..."
|
|
48
|
+
puts "[#{replication_slot}] Watcher finished for #{replication_slot}, auto restarting in #{backoff_time.floor(2)}..."
|
|
44
49
|
sleep backoff_time
|
|
45
|
-
puts "
|
|
50
|
+
puts "[#{replication_slot}] Restarting"
|
|
46
51
|
redo
|
|
47
52
|
end
|
|
48
53
|
rescue ArgumentError
|
|
49
54
|
raise
|
|
50
55
|
rescue StandardError => err
|
|
56
|
+
Wal.hooks[:on_slot_error]&.call(err, slot, config)
|
|
57
|
+
|
|
58
|
+
Wal.logger&.error("[#{replication_slot}] Error #{err}")
|
|
59
|
+
Wal.logger&.error([err.message, *err.backtrace].join("\n"))
|
|
60
|
+
|
|
51
61
|
if retries < max_retries
|
|
52
|
-
Wal.logger&.error("[#{replication_slot}] Error #{err}")
|
|
53
|
-
Wal.logger&.error([err.message, *err.backtrace].join("\n"))
|
|
54
62
|
retries += 1
|
|
55
63
|
backoff_time = backoff_exponent ? (backoff * retries) ** backoff_exponent : backoff
|
|
56
|
-
puts "Restarting #{replication_slot} in #{backoff_time.floor(2)}s..."
|
|
64
|
+
puts "#{replication_slot}] Restarting #{replication_slot} in #{backoff_time.floor(2)}s..."
|
|
57
65
|
sleep backoff_time
|
|
58
|
-
puts "Restarting #{replication_slot}"
|
|
66
|
+
puts "#{replication_slot}] Restarting #{replication_slot}"
|
|
59
67
|
retry
|
|
60
68
|
end
|
|
61
69
|
raise
|
|
@@ -105,12 +113,12 @@ module Wal
|
|
|
105
113
|
end
|
|
106
114
|
|
|
107
115
|
def run_forked_workers(workers_slots)
|
|
108
|
-
Wal.
|
|
116
|
+
Wal.hooks[:before_fork]&.call(workers_slots)
|
|
109
117
|
|
|
110
118
|
workers_slots.each do |worker_name, slot_configs|
|
|
111
119
|
pid = fork_worker(worker_name, slot_configs)
|
|
112
120
|
@child_pids << pid
|
|
113
|
-
puts "Spawned worker '#{worker_name}' with PID #{pid}"
|
|
121
|
+
puts "[#{worker_name}] Spawned worker '#{worker_name}' with PID #{pid}"
|
|
114
122
|
end
|
|
115
123
|
|
|
116
124
|
@ping_thread = start_ping_thread
|
|
@@ -122,7 +130,7 @@ module Wal
|
|
|
122
130
|
|
|
123
131
|
def fork_worker(worker_name, slot_configs)
|
|
124
132
|
Process.fork do
|
|
125
|
-
Wal.
|
|
133
|
+
Wal.hooks[:after_fork]&.call(worker_name, slot_configs)
|
|
126
134
|
puts "[#{worker_name}] Starting worker process (PID: #{Process.pid})"
|
|
127
135
|
worker = Worker.new(name: worker_name, slot_configs: slot_configs, db_config: db_config)
|
|
128
136
|
worker.run
|
data/lib/wal/version.rb
CHANGED
data/lib/wal.rb
CHANGED
|
@@ -16,22 +16,30 @@ require_relative "wal/version"
|
|
|
16
16
|
module Wal
|
|
17
17
|
class << self
|
|
18
18
|
attr_accessor :logger
|
|
19
|
-
attr_accessor :
|
|
19
|
+
attr_accessor :hooks
|
|
20
20
|
|
|
21
21
|
def logger
|
|
22
22
|
@logger ||= Logger.new($stdout, level: :info)
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
def
|
|
26
|
-
@
|
|
25
|
+
def hooks
|
|
26
|
+
@hooks ||= {}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def on_slot_finished(&block)
|
|
30
|
+
hooks[:on_slot_finished] = block
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def on_slot_error(&block)
|
|
34
|
+
hooks[:on_slot_error] = block
|
|
27
35
|
end
|
|
28
36
|
|
|
29
37
|
def before_fork(&block)
|
|
30
|
-
|
|
38
|
+
hooks[:before_fork] = block
|
|
31
39
|
end
|
|
32
40
|
|
|
33
41
|
def after_fork(&block)
|
|
34
|
-
|
|
42
|
+
hooks[:after_fork] = block
|
|
35
43
|
end
|
|
36
44
|
end
|
|
37
45
|
|
data/rbi/wal.rbi
CHANGED
|
@@ -7,17 +7,26 @@ module Wal
|
|
|
7
7
|
UpdateEvent,
|
|
8
8
|
DeleteEvent,
|
|
9
9
|
) }
|
|
10
|
-
VERSION = "0.0.
|
|
10
|
+
VERSION = "0.0.34"
|
|
11
11
|
|
|
12
12
|
class << self
|
|
13
13
|
sig { returns(T.class_of(Logger)) }
|
|
14
14
|
attr_accessor :logger
|
|
15
15
|
|
|
16
|
-
sig { params(block: T.proc.void).void }
|
|
16
|
+
sig { params(block: T.proc.params(worker_name: T.untyped).void).void }
|
|
17
17
|
def before_fork(&block); end
|
|
18
18
|
|
|
19
|
-
sig { params(block: T.proc.void).void }
|
|
19
|
+
sig { params(block: T.proc.params(worker_name: String, slot_configs: T.untyped).void).void }
|
|
20
20
|
def after_fork(&block); end
|
|
21
|
+
|
|
22
|
+
sig { params(block: T.proc.params(slot: String, config: T.untyped).void).void }
|
|
23
|
+
def on_slot_start(&block); end
|
|
24
|
+
|
|
25
|
+
sig { params(block: T.proc.params(error: StandardError, slot: String, config: T.untyped).void).void }
|
|
26
|
+
def on_slot_error(&block); end
|
|
27
|
+
|
|
28
|
+
sig { params(block: T.proc.params(slot: String, config: T.untyped).void).void }
|
|
29
|
+
def on_slot_finish(&block); end
|
|
21
30
|
end
|
|
22
31
|
|
|
23
32
|
sig { params(block: T.proc.params(config: T.class_of(Wal)).void).void }
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: wal
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.34
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rodrigo Navarro
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-02-
|
|
10
|
+
date: 2026-02-11 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: pg
|