wal 0.0.32 → 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: e8f18e327f41668911967dbb73d0f6c51ab43f2b5d1d25b7c39b5f5130a04081
4
- data.tar.gz: d0ffc96073a5faa4fd3949a02348b029bd206196fdd61c71883e5115ee53d6fa
3
+ metadata.gz: 79eda85dc0f833f81fc5c4778b7f8333559308f46111758e09977ec3dc98461c
4
+ data.tar.gz: 470232c05cf0dc4ee5d55448ce6b88aa57373c53f504dda3526482a3473d3dbc
5
5
  SHA512:
6
- metadata.gz: effddb80b5b8093e572e65a587f5b7975cb20750aa39e7c329cb7358bd099d3bd12110648ee5b11c4dd45d791c1d050e6b0e7e82c7585c1678f9b1c532d54395
7
- data.tar.gz: 35e21330e4da4297adcf4cbfa67ce939b5894981b352acfbc7fe8c02b1083436d037e9f7be45445445ef621ec783c84ce866f8636379609d7ff8c62e7c9fd392
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
@@ -79,18 +79,32 @@ module Wal
79
79
  end
80
80
  end
81
81
 
82
- attr_reader :config_file, :db_config
82
+ attr_reader :config, :db_config
83
83
 
84
- def initialize(config_file:, db_config:)
85
- @config_file = config_file
84
+ def initialize(config:, db_config:)
85
+ @config = config
86
86
  @db_config = db_config
87
87
  @child_pids = []
88
88
  end
89
89
 
90
90
  def start
91
- slots = YAML.load_file(config_file)["slots"]
92
- workers_slots = slots.group_by { |_slot, config| config["worker"] || "default" }
91
+ workers_slots = config["slots"].group_by { |_slot, slot_config| slot_config["worker"] || "default" }
93
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
106
+
107
+ def run_forked_workers(workers_slots)
94
108
  Wal.fork_hooks[:before_fork]&.call
95
109
 
96
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.32"
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.32"
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.32
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-28 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