wal 0.0.31 → 0.0.33

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ebd8285e94c341f2e9c14bc71f7c80177153eddc82ab55fe302ddfa9c8f420fc
4
- data.tar.gz: 261f5c87be8a50e074fb445c70a3ef1f04fdb95a98800d2e4408b28dda14c1cf
3
+ metadata.gz: 79eda85dc0f833f81fc5c4778b7f8333559308f46111758e09977ec3dc98461c
4
+ data.tar.gz: 470232c05cf0dc4ee5d55448ce6b88aa57373c53f504dda3526482a3473d3dbc
5
5
  SHA512:
6
- metadata.gz: '0840147d093d96603562fbdd2ea081c52f8760d6eb51cb666effa904a0b5bc710fccabaefd08c56bafff2e903cd7ad227b55ab408b27c97b48387a9151778d48'
7
- data.tar.gz: 22c894fbfe102e3340b6dfd60603b42bb285178155c65a1887e44434af55e68d23ed548cbc52f4e7cabafb5e9ac3aa8a882ad60350b635645478242f04db374c
6
+ metadata.gz: e30d85d2e335ab143daa5de2962912009a340ba279ab47e4f531e6577ada0eb2cca22148f10601d75fc992bbb35cf8b081ebc02b698189d1ab4f841029367254
7
+ data.tar.gz: 262104fb88bd6cb51ad181f9d8bea74e25d9f9798a5f04969ec33c29d71ccd9c9fb4cd22ba2b089075c5a4458d028597c5cfabe24a5086578bd297b67598be76
data/exe/wal CHANGED
@@ -7,7 +7,7 @@ begin
7
7
  Usage:
8
8
  wal watch --watcher <watcher-class>
9
9
  (--slot <replication-slot> | --tmp-slot)
10
- [--publication=<publication>...]
10
+ --publication <publication>...
11
11
  [--replicator <replicator-class>]
12
12
  wal start <config-file>
13
13
 
@@ -16,7 +16,7 @@ begin
16
16
  --watcher=<watcher-class> The watcher class to be used to listen for WAL changes.
17
17
  --slot=<replication-slot> The replication slot that will be used.
18
18
  --tmp-slot Use a temporary replication slot.
19
- [--publication=<publication>...] Force using the informed Postgres publications.
19
+ [--publication=<publication>...] Postgres publications to subscribe to.
20
20
  [--replicator=<replicatior_class>] Change the replication driver class
21
21
  DOCOPT
22
22
  rescue Docopt::Exit => err
@@ -28,24 +28,18 @@ require "./config/environment"
28
28
 
29
29
  db_config = ActiveRecord::Base.configurations.configs_for(name: "primary").configuration_hash
30
30
 
31
- def watch(db_config, cli)
32
- watcher = cli["--watcher"].constantize.new
33
- use_temporary_slot = cli["--tmp-slot"] || false
34
- replication_slot = cli["--slot"]
35
- replication_slot = replication_slot.presence || "wal_watcher_#{SecureRandom.alphanumeric(4)}" if use_temporary_slot
36
- publications = cli["--publication"] || []
37
- replicator_class = cli["--replicator"].presence&.constantize || Wal::Replicator
38
-
39
- puts "Watcher started for #{replication_slot} slot (#{publications.join(", ")})"
40
- replicator_class
41
- .new(replication_slot:, use_temporary_slot:, db_config:)
42
- .replicate_forever(Wal::LoggingWatcher.new(replication_slot, watcher), publications:)
43
- puts "Watcher finished for #{replication_slot}"
44
- end
45
-
46
31
  if cli["watch"]
47
- watch(db_config, cli)
32
+ config = {
33
+ "watcher" => cli["--watcher"],
34
+ "temporary" => cli["--tmp-slot"],
35
+ "publications" => cli["--publication"] || [],
36
+ "replicator" => cli["--replicator"],
37
+ }
38
+ slot = cli["--slot"].presence || "wal_watcher_#{SecureRandom.alphanumeric(4)}"
39
+ runner = Wal::Runner.new(config: { "slots" => { slot => config } }, db_config:)
40
+ runner.start
48
41
  elsif cli["start"]
49
- runner = Wal::Runner.new(config_file: cli["<config-file>"], db_config:)
42
+ config = YAML.load_file(cli["<config-file>"])
43
+ runner = Wal::Runner.new(config:, db_config:)
50
44
  runner.start
51
45
  end
@@ -5,6 +5,8 @@ module Wal
5
5
  def initialize(slot, watcher)
6
6
  @slot = slot
7
7
  @watcher = watcher
8
+ @actions = Set.new
9
+ @tables = Set.new
8
10
  end
9
11
 
10
12
  def should_watch_table?(table)
@@ -26,17 +28,27 @@ module Wal
26
28
  when Wal::CommitTransactionEvent
27
29
  if @count > 0
28
30
  elapsed = ((Time.now - @start) * 1000.0).round(1)
29
- Wal.logger&.info("[#{@slot}] Commit transaction=#{event.transaction_id} elapsed=#{elapsed} events=#{@count}")
31
+ actions = " actions=#{@actions.sort.join(",")}" unless @actions.empty?
32
+ tables = " tables=#{@tables.sort.join(",")}" unless @tables.empty?
33
+ Wal.logger&.info("[#{@slot}] Commit transaction=#{event.transaction_id} elapsed=#{elapsed} events=#{@count}#{actions}#{tables}")
30
34
  end
35
+ @actions.clear
36
+ @tables.clear
31
37
  when Wal::InsertEvent
32
38
  Wal.logger&.debug("[#{@slot}] Insert transaction=#{event.transaction_id} table=#{event.table} primary_key=#{event.primary_key}")
33
39
  @count += 1
40
+ @actions << :insert
41
+ @tables << event.table
34
42
  when Wal::UpdateEvent
35
43
  Wal.logger&.debug("[#{@slot}] Update transaction=#{event.transaction_id} table=#{event.table} primary_key=#{event.primary_key}")
36
44
  @count += 1
45
+ @actions << :update
46
+ @tables << event.table
37
47
  when Wal::DeleteEvent
38
48
  Wal.logger&.debug("[#{@slot}] Delete transaction=#{event.transaction_id} table=#{event.table} primary_key=#{event.primary_key}")
39
49
  @count += 1
50
+ @actions << :delete
51
+ @tables << event.table
40
52
  else
41
53
  @count += 1
42
54
  end
data/lib/wal/runner.rb CHANGED
@@ -23,6 +23,7 @@ module Wal
23
23
  temporary = config["temporary"] || false
24
24
  publications = config["publications"] || []
25
25
  replicator_class = config["replicator"].presence&.constantize || Wal::Replicator
26
+ replicator_params = config["replicator_params"]&.transform_keys(&:to_sym) || {}
26
27
  auto_restart = config["auto_restart"].nil? || config["auto_restart"]
27
28
  max_retries = config["retries"]&.to_i || (2**32 - 1)
28
29
  backoff = config["retry_backoff"]&.to_f || 1
@@ -35,7 +36,7 @@ module Wal
35
36
 
36
37
  begin
37
38
  replicator_class
38
- .new(replication_slot:, use_temporary_slot:, db_config:)
39
+ .new(db_config:, **replicator_params, replication_slot:, use_temporary_slot:)
39
40
  .replicate_forever(Wal::LoggingWatcher.new(replication_slot, watcher), publications:)
40
41
  if auto_restart
41
42
  backoff_time = backoff_exponent ? (backoff * retries) ** backoff_exponent : backoff
@@ -44,6 +45,8 @@ module Wal
44
45
  puts "Restarting #{replication_slot}"
45
46
  redo
46
47
  end
48
+ rescue ArgumentError
49
+ raise
47
50
  rescue StandardError => err
48
51
  if retries < max_retries
49
52
  Wal.logger&.error("[#{replication_slot}] Error #{err}")
@@ -76,18 +79,32 @@ module Wal
76
79
  end
77
80
  end
78
81
 
79
- attr_reader :config_file, :db_config
82
+ attr_reader :config, :db_config
80
83
 
81
- def initialize(config_file:, db_config:)
82
- @config_file = config_file
84
+ def initialize(config:, db_config:)
85
+ @config = config
83
86
  @db_config = db_config
84
87
  @child_pids = []
85
88
  end
86
89
 
87
90
  def start
88
- slots = YAML.load_file(config_file)["slots"]
89
- workers_slots = slots.group_by { |_slot, config| config["worker"] || "default" }
91
+ workers_slots = config["slots"].group_by { |_slot, slot_config| slot_config["worker"] || "default" }
92
+
93
+ if workers_slots.size == 1
94
+ run_single_worker(workers_slots.first)
95
+ else
96
+ run_forked_workers(workers_slots)
97
+ end
98
+ end
99
+
100
+ def run_single_worker((worker_name, slot_configs))
101
+ @ping_thread = start_ping_thread
102
+ puts "[#{worker_name}] Starting worker process (PID: #{Process.pid})"
103
+ worker = Worker.new(name: worker_name, slot_configs: slot_configs, db_config: db_config)
104
+ worker.run
105
+ end
90
106
 
107
+ def run_forked_workers(workers_slots)
91
108
  Wal.fork_hooks[:before_fork]&.call
92
109
 
93
110
  workers_slots.each do |worker_name, slot_configs|
data/lib/wal/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Wal
4
- VERSION = "0.0.31"
4
+ VERSION = "0.0.33"
5
5
  end
data/rbi/wal.rbi CHANGED
@@ -7,7 +7,7 @@ module Wal
7
7
  UpdateEvent,
8
8
  DeleteEvent,
9
9
  ) }
10
- VERSION = "0.0.31"
10
+ VERSION = "0.0.33"
11
11
 
12
12
  class << self
13
13
  sig { returns(T.class_of(Logger)) }
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.31
4
+ version: 0.0.33
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Navarro
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2026-01-27 00:00:00.000000000 Z
10
+ date: 2026-02-09 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: pg