julewire-karafka 1.1.2 → 1.1.3

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: 97d34d8fbe897efb7ce015f2255693f44c09b942e55b8289cb023b197ff134d8
4
- data.tar.gz: cac00f978d4c2fcdf288b33dca657a980e7426978162caadf3dcd11e6437e7a2
3
+ metadata.gz: 26a7119151755c216ae01a615690321a0b3ae64fd3d584073163942c8dd0df49
4
+ data.tar.gz: 893718199e8e4dc0431fa7f981fe75d3d5628c7de9461808e0c077423f8c3010
5
5
  SHA512:
6
- metadata.gz: 7f82481e87e01709f27854367d7c0655a46991431520304de1c7c9368c625ec7aa9a516619b63f8668a7ac988d4da4719268c5c52ee8e35641f5e01b8fe2cfa7
7
- data.tar.gz: f7ffef746dbda3fdb9ac5892520ff0fcfe0923a8b9fc8b4a75f6a858acf73677683b5c0d091e00ebea3c951194a92db99145af9dcfa76ec0ae9f3a822093fae8
6
+ metadata.gz: 4779ebb58608a479af2179519b24449f1faa8b5ee1f71336b62540588397e1949af1acc063d3ceb63f4eeda9e4ffd22c681f767fea51463a8675474c29cc077f
7
+ data.tar.gz: fbf448301c59a4f2c3195cb1e9ebad9e1ce88da6be889046deef941a06413987b8ca30cf3670caedad1e1cf87b0b12bfaab9ef0d90bed02b9ba1dd412481563c
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  ## Unreleased
2
2
 
3
+ ## 1.1.3 - 2026-08-09
4
+
5
+ - Quiesce Julewire resources without emitting after Karafka pre-fork preparation.
6
+ - Test against Karafka 2.6 and remove reflective monitor-profile lookup.
7
+ - Require julewire-core 1.1.3.
8
+ - Refresh development tooling and compatibility locksets.
9
+
3
10
  ## 1.1.2 - 2026-08-02
4
11
 
5
12
  - Refresh development and compatibility dependency locksets.
data/README.md CHANGED
@@ -45,7 +45,8 @@ Default behavior:
45
45
  - important consumer and producer monitor events become point records
46
46
  - message headers carry Julewire propagation carriers
47
47
  - `with_message` restores message context and adds message attributes
48
- - Karafka fork hooks call `Julewire.after_fork!`
48
+ - Karafka swarm hooks quiesce Julewire before manager forks and reset it after
49
+ manager and worker forks
49
50
  - text logger listeners are not parsed or deduplicated
50
51
 
51
52
  Inbound Kafka carriers are trusted by default for internal service traffic. Set
@@ -4,9 +4,13 @@
4
4
  Set `consumer_event_names = :all` to subscribe to Karafka's registered monitor
5
5
  events, or pass an explicit event list for application policy. If the monitor
6
6
  cannot expose its registered events, `:all` uses the important profile.
7
+ `swarm.manager.before_fork` is reserved for lifecycle preparation and is never
8
+ routed through the generic event listener, even when selected explicitly.
7
9
 
8
10
  `install!` also subscribes lightweight handlers for
9
- `swarm.node.after_fork` and `swarm.manager.after_fork`. Those handlers call
11
+ `swarm.manager.before_fork`, `swarm.node.after_fork`, and
12
+ `swarm.manager.after_fork`. The manager hook calls `Julewire.before_fork!` so
13
+ unsafe resources drain before process creation. The after-fork handlers call
10
14
  `Julewire.after_fork!` so inherited mutexes, counters, async transports, and
11
15
  process-local context are reset in Karafka forked processes.
12
16
 
@@ -34,7 +34,7 @@ Gem::Specification.new do |spec|
34
34
  spec.executables = []
35
35
  spec.require_paths = ["lib"]
36
36
 
37
- spec.add_dependency "julewire-core", ">= 1.1.0"
37
+ spec.add_dependency "julewire-core", ">= 1.1.3"
38
38
  spec.add_dependency "karafka", ">= 2.5"
39
39
  spec.add_dependency "waterdrop", ">= 2.10"
40
40
  spec.add_dependency "zeitwerk", ">= 2.8.1"
@@ -12,7 +12,6 @@ module Julewire
12
12
  DEBUG_CONSUMER_EVENTS = %w[
13
13
  connection.listener.fetch_loop
14
14
  statistics.emitted
15
- swarm.manager.before_fork
16
15
  swarm.manager.control
17
16
  ].freeze
18
17
 
@@ -4,11 +4,13 @@ module Julewire
4
4
  module Karafka
5
5
  module ForkHooks
6
6
  EVENTS = %w[
7
+ swarm.manager.before_fork
7
8
  swarm.node.after_fork
8
9
  swarm.manager.after_fork
9
10
  ].freeze
11
+ BEFORE_FORK_EVENT = "swarm.manager.before_fork"
10
12
  INSTALL_STATE = Core::Integration::IvarState.new(:@julewire_karafka_fork_hooks_state)
11
- private_constant :EVENTS, :INSTALL_STATE
13
+ private_constant :BEFORE_FORK_EVENT, :EVENTS, :INSTALL_STATE
12
14
 
13
15
  class << self
14
16
  def subscribe!(monitor, configuration:)
@@ -26,8 +28,12 @@ module Julewire
26
28
  end
27
29
 
28
30
  def handle(event_name, _event)
29
- IntegrationHealth.with_failure_health(action: :after_fork, component: :fork_hooks, event: event_name) do
30
- Julewire.after_fork!
31
+ if event_name == BEFORE_FORK_EVENT
32
+ Julewire.before_fork!
33
+ else
34
+ IntegrationHealth.with_failure_health(action: :after_fork, component: :fork_hooks, event: event_name) do
35
+ Julewire.after_fork!
36
+ end
31
37
  end
32
38
  end
33
39
 
@@ -10,7 +10,7 @@ module Julewire
10
10
 
11
11
  ForkHooks.subscribe!(monitor, configuration: configuration)
12
12
  if configuration.consumer_events?
13
- MonitorSubscription.install!(monitor, configuration: configuration, profile: :consumer)
13
+ MonitorSubscription.install!(monitor, configuration: configuration, profile: MonitorProfiles.consumer)
14
14
  end
15
15
  monitor
16
16
  end
@@ -3,43 +3,13 @@
3
3
  module Julewire
4
4
  module Karafka
5
5
  class MonitorListener
6
- Profile = Data.define(
7
- :component,
8
- :event_prefix,
9
- :logger_name,
10
- :messaging_role,
11
- :config_method,
12
- :important_events,
13
- :severity
14
- )
15
-
16
- CONSUMER_PROFILE = Profile.new(
17
- component: :listener,
18
- event_prefix: "karafka",
19
- logger_name: "Karafka.monitor",
20
- messaging_role: :consumer,
21
- config_method: :consumer_event_names,
22
- important_events: Configuration::IMPORTANT_CONSUMER_EVENT_NAMES,
23
- severity: ->(name, event, payload) { EventSeverity.consumer(name, event: event, payload: payload) }
24
- ).freeze
25
- PRODUCER_PROFILE = Profile.new(
26
- component: :waterdrop_listener,
27
- event_prefix: "waterdrop",
28
- logger_name: "WaterDrop.monitor",
29
- messaging_role: :producer,
30
- config_method: :producer_event_names,
31
- important_events: Configuration::IMPORTANT_PRODUCER_EVENT_NAMES,
32
- severity: ->(name, _event, payload) { EventSeverity.producer(name, payload) }
33
- ).freeze
34
- private_constant :Profile, :CONSUMER_PROFILE, :PRODUCER_PROFILE
35
-
36
6
  class << self
37
7
  def consumer(configuration = Configuration.new)
38
- new(configuration, profile: CONSUMER_PROFILE)
8
+ new(configuration, profile: MonitorProfiles.consumer)
39
9
  end
40
10
 
41
11
  def producer(configuration = Configuration.new)
42
- new(configuration, profile: PRODUCER_PROFILE)
12
+ new(configuration, profile: MonitorProfiles.producer)
43
13
  end
44
14
  end
45
15
 
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Julewire
4
+ module Karafka
5
+ module MonitorProfiles
6
+ Profile = Data.define(
7
+ :component,
8
+ :event_prefix,
9
+ :logger_name,
10
+ :messaging_role,
11
+ :config_method,
12
+ :important_events,
13
+ :reserved_events,
14
+ :severity
15
+ )
16
+
17
+ CONSUMER = Profile.new(
18
+ component: :listener,
19
+ event_prefix: "karafka",
20
+ logger_name: "Karafka.monitor",
21
+ messaging_role: :consumer,
22
+ config_method: :consumer_event_names,
23
+ important_events: Configuration::IMPORTANT_CONSUMER_EVENT_NAMES,
24
+ reserved_events: %w[swarm.manager.before_fork].freeze,
25
+ severity: ->(name, event, payload) { EventSeverity.consumer(name, event: event, payload: payload) }
26
+ ).freeze
27
+ PRODUCER = Profile.new(
28
+ component: :waterdrop_listener,
29
+ event_prefix: "waterdrop",
30
+ logger_name: "WaterDrop.monitor",
31
+ messaging_role: :producer,
32
+ config_method: :producer_event_names,
33
+ important_events: Configuration::IMPORTANT_PRODUCER_EVENT_NAMES,
34
+ reserved_events: [].freeze,
35
+ severity: ->(name, _event, payload) { EventSeverity.producer(name, payload) }
36
+ ).freeze
37
+ private_constant :Profile, :CONSUMER, :PRODUCER
38
+
39
+ class << self
40
+ def consumer = CONSUMER
41
+
42
+ def producer = PRODUCER
43
+ end
44
+ end
45
+
46
+ private_constant :MonitorProfiles
47
+ end
48
+ end
@@ -3,12 +3,6 @@
3
3
  module Julewire
4
4
  module Karafka
5
5
  module MonitorSubscription
6
- PROFILE_CONSTANTS = {
7
- consumer: :CONSUMER_PROFILE,
8
- producer: :PRODUCER_PROFILE
9
- }.freeze
10
- private_constant :PROFILE_CONSTANTS
11
-
12
6
  class << self
13
7
  def subscribe(monitor, event_name, component:, &)
14
8
  return false unless monitor.respond_to?(:subscribe)
@@ -20,7 +14,6 @@ module Julewire
20
14
  end
21
15
 
22
16
  def install!(monitor, profile:, configuration:)
23
- profile = monitor_listener_profile(profile)
24
17
  state = subscription_state(monitor, profile)
25
18
  listener = listener_for(state, configuration, profile)
26
19
  subscriptions = subscriptions_for(state)
@@ -41,11 +34,6 @@ module Julewire
41
34
 
42
35
  private
43
36
 
44
- def monitor_listener_profile(profile)
45
- constant_name = PROFILE_CONSTANTS.fetch(profile)
46
- MonitorListener.const_get(constant_name)
47
- end
48
-
49
37
  def listener_for(state, configuration, profile)
50
38
  listener = state&.fetch(:listener)
51
39
  if listener
@@ -83,16 +71,17 @@ module Julewire
83
71
 
84
72
  def event_names(monitor, configuration, profile)
85
73
  configured = configuration.public_send(profile.config_method)
86
- return profile.important_events if configured == :important
87
-
88
- if all_events?(configured)
89
- available_events = available_events_for(monitor)
90
- return available_events unless available_events.empty?
91
-
92
- return profile.important_events
93
- end
74
+ selected_events =
75
+ if configured == :important
76
+ profile.important_events
77
+ elsif all_events?(configured)
78
+ available_events = available_events_for(monitor)
79
+ available_events.empty? ? profile.important_events : available_events
80
+ else
81
+ Array(configured)
82
+ end
94
83
 
95
- Array(configured)
84
+ selected_events - profile.reserved_events
96
85
  end
97
86
 
98
87
  def available_events_for(monitor)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Julewire
4
4
  module Karafka
5
- VERSION = "1.1.2"
5
+ VERSION = "1.1.3"
6
6
  end
7
7
  end
@@ -41,7 +41,7 @@ module Julewire
41
41
  return unless producer.respond_to?(:monitor)
42
42
 
43
43
  monitor = producer.monitor
44
- MonitorSubscription.install!(monitor, configuration: configuration, profile: :producer)
44
+ MonitorSubscription.install!(monitor, configuration: configuration, profile: MonitorProfiles.producer)
45
45
  rescue StandardError => e
46
46
  IntegrationHealth.record_failure(e, action: :install, component: :waterdrop_installer)
47
47
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: julewire-karafka
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Grebennik
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: 1.1.0
18
+ version: 1.1.3
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: 1.1.0
25
+ version: 1.1.3
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: karafka
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -95,6 +95,7 @@ files:
95
95
  - lib/julewire/karafka/message_execution.rb
96
96
  - lib/julewire/karafka/messaging_attributes.rb
97
97
  - lib/julewire/karafka/monitor_listener.rb
98
+ - lib/julewire/karafka/monitor_profiles.rb
98
99
  - lib/julewire/karafka/monitor_subscription.rb
99
100
  - lib/julewire/karafka/payload_reader.rb
100
101
  - lib/julewire/karafka/version.rb