julewire-core 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 +4 -4
- data/CHANGELOG.md +5 -0
- data/docs/contracts.md +5 -2
- data/docs/extensions-and-api.md +14 -5
- data/docs/outputs-and-lifecycle.md +15 -0
- data/lib/julewire/core/destinations/chaos_output.rb +7 -0
- data/lib/julewire/core/destinations/collection.rb +35 -0
- data/lib/julewire/core/destinations/destination.rb +8 -0
- data/lib/julewire/core/destinations/synchronized_output.rb +11 -0
- data/lib/julewire/core/destinations/tail_sampling.rb +17 -0
- data/lib/julewire/core/facade_methods.rb +5 -0
- data/lib/julewire/core/integration/before_fork_hooks.rb +32 -0
- data/lib/julewire/core/integration/fork_hooks.rb +2 -7
- data/lib/julewire/core/integration/hook_names.rb +16 -0
- data/lib/julewire/core/integration/lifecycle.rb +4 -0
- data/lib/julewire/core/processing/pipeline.rb +4 -0
- data/lib/julewire/core/runtime.rb +13 -0
- data/lib/julewire/core/runtime_registry.rb +16 -0
- data/lib/julewire/core/unsafe_fork_error.rb +8 -0
- data/lib/julewire/core/version.rb +1 -1
- data/lib/julewire/core.rb +1 -0
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1706c04d0b1576af41d10b18b1e7288b2e9a80f3ab599298cf7fafefa9c6887b
|
|
4
|
+
data.tar.gz: 7e7a34704951f6e420dbf0a91d5eab8bad5ce099f4c70e5913e14d4f585ef8e4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e5aaa3aeec9061a87b47d54a1b5a36ff4c7b901492f450325a9f3e91d10857700c648e837f88b50f0c3b9dd7c75f9810ebaaff196c8c96235d13a655788d234e
|
|
7
|
+
data.tar.gz: 2f7dc4648b5587e2e498005204b5af7e9f02757336d89524a2309a3515c22e08e151063d41b531a28f14efd3716d338817f090fb8cdfcb47e328bc2f746d42e2
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
## Unreleased
|
|
2
2
|
|
|
3
|
+
## 1.1.3 - 2026-08-09
|
|
4
|
+
|
|
5
|
+
- Add fail-loud pre-fork hooks with shared timeout budgets and reverse rollback.
|
|
6
|
+
- Refresh development tooling and compatibility locksets.
|
|
7
|
+
|
|
3
8
|
## 1.1.2 - 2026-08-02
|
|
4
9
|
|
|
5
10
|
- Refresh development and compatibility dependency locksets.
|
data/docs/contracts.md
CHANGED
|
@@ -9,7 +9,9 @@ These APIs are for application code and scripts:
|
|
|
9
9
|
|
|
10
10
|
- Runtime configuration and lifecycle: `Julewire.configure`,
|
|
11
11
|
`Julewire.config`, `Julewire.reset!`, `Julewire.flush`, `Julewire.close`,
|
|
12
|
-
`Julewire.after_fork!`, and `Julewire.health`.
|
|
12
|
+
`Julewire.before_fork!`, `Julewire.after_fork!`, and `Julewire.health`.
|
|
13
|
+
- `Julewire::UnsafeForkError` for pre-fork safety failures that must abort
|
|
14
|
+
process creation.
|
|
13
15
|
- `Julewire.runtime` for explicit secondary pipelines with independent
|
|
14
16
|
configuration, destinations, processors, health, and lifecycle.
|
|
15
17
|
- `Julewire.labels` for process labels shared by the active runtime.
|
|
@@ -91,7 +93,8 @@ but they are not intended as general application API:
|
|
|
91
93
|
- `Julewire::Core::Integration::Values::Shape` for normalized timestamps, payload
|
|
92
94
|
normalization, field appends, and source-location shaping.
|
|
93
95
|
- `Julewire::Core::Integration::Lifecycle` for optional require containment and
|
|
94
|
-
process-local
|
|
96
|
+
process-local before/after-fork hooks. Hook identifiers are strict Symbols;
|
|
97
|
+
before-fork failures propagate while after-fork failures are health-contained.
|
|
95
98
|
- `Julewire::Core::Integration` helper classes/modules for one-time ivar state,
|
|
96
99
|
subscriber install helpers, event-subscriber health wrappers, config settings
|
|
97
100
|
helpers, and subscription handles.
|
data/docs/extensions-and-api.md
CHANGED
|
@@ -281,10 +281,12 @@ return without raising unless they return `false`.
|
|
|
281
281
|
dropped record; a plain `false` is a rejected record and calls `on_drop` with
|
|
282
282
|
`:destination_rejected`.
|
|
283
283
|
|
|
284
|
-
Custom destinations may
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
284
|
+
Custom destinations may implement `before_fork!(timeout:)` to drain and stop
|
|
285
|
+
resources that cannot survive a process fork. Returning `false` rejects fork
|
|
286
|
+
preparation; raising reports the failure and aborts preparation. Destinations
|
|
287
|
+
may also implement `after_fork!` for fork reset and `resource_identity` when
|
|
288
|
+
multiple destinations share the same closeable resource. Transport adapters
|
|
289
|
+
may expose adapter-specific lifecycle methods such as `reopen`.
|
|
288
290
|
|
|
289
291
|
The registered `:tail_sampling` destination kind wraps another destination for
|
|
290
292
|
execution-level tail sampling. It buffers execution records until a summary
|
|
@@ -399,12 +401,17 @@ should accept keyword metadata.
|
|
|
399
401
|
`contracts.md` owns the public facade inventory. This section covers usage
|
|
400
402
|
details that extension and integration authors usually need.
|
|
401
403
|
|
|
404
|
+
Integrations can register a fail-loud safety hook with
|
|
405
|
+
`Julewire::Core::Integration::Lifecycle.register_before_fork(:integration_name,
|
|
406
|
+
component: :component_name) { ... }`. It runs after destinations have quiesced;
|
|
407
|
+
an exception aborts preparation and resumes destinations already prepared.
|
|
408
|
+
|
|
402
409
|
Integrations that keep process-local state can register a reset hook with
|
|
403
410
|
`Julewire::Core::Integration::Lifecycle.register_after_fork(:integration_name,
|
|
404
411
|
component: :component_name) { ... }`. The hook runs after core has refreshed its
|
|
405
412
|
own process-local state and after the active pipeline has forwarded
|
|
406
413
|
`after_fork!` to destinations.
|
|
407
|
-
|
|
414
|
+
All integration and component hook names are strict identifiers: pass non-empty Symbols.
|
|
408
415
|
String or non-Symbol names raise at registration and are never normalized.
|
|
409
416
|
|
|
410
417
|
`Julewire.observe_self!(runtime_name = :default, target: :meta)` starts a
|
|
@@ -431,6 +438,8 @@ Lifecycle:
|
|
|
431
438
|
|
|
432
439
|
- `Integration::Lifecycle.require_optional(path)` for contained optional
|
|
433
440
|
requires.
|
|
441
|
+
- `Integration::Lifecycle.register_before_fork(:integration_name,
|
|
442
|
+
component: :component_name) { ... }` for fail-loud process preparation.
|
|
434
443
|
- `Integration::Lifecycle.register_after_fork(:integration_name,
|
|
435
444
|
component: :component_name) { ... }` for process-local integration state.
|
|
436
445
|
- `Integration::IvarState` for idempotent framework subscriber state.
|
|
@@ -151,6 +151,11 @@ attempts later destinations after a previous lifecycle call returns.
|
|
|
151
151
|
out, `Julewire.close` returns `false`, but later emits still drop as
|
|
152
152
|
`runtime_closed` until the next `configure` or `reset!`.
|
|
153
153
|
|
|
154
|
+
`Julewire.before_fork!` gives destinations a bounded opportunity to drain and
|
|
155
|
+
quiesce resources that cannot safely survive `Process.fork`. Preparation
|
|
156
|
+
failures propagate so the process manager can abort the fork. Stop application
|
|
157
|
+
work that can emit or create process-local workers before calling it.
|
|
158
|
+
|
|
154
159
|
`Julewire.after_fork!` resets process-local counters, failure snapshots,
|
|
155
160
|
current context, warning state, schedulers, and registries that cannot be
|
|
156
161
|
shared with the child process. It also forwards `after_fork!` to destinations
|
|
@@ -159,6 +164,16 @@ registered through core. File, socket, queue, and async transports should
|
|
|
159
164
|
reopen worker-local resources from their destination or output `after_fork!`
|
|
160
165
|
method.
|
|
161
166
|
|
|
167
|
+
Forking servers must pair the lifecycle calls around the actual fork:
|
|
168
|
+
|
|
169
|
+
```ruby
|
|
170
|
+
before_fork { Julewire.before_fork! }
|
|
171
|
+
on_worker_boot { Julewire.after_fork! }
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
The parent may also call `Julewire.after_fork!` when it must resume destinations
|
|
175
|
+
between worker forks.
|
|
176
|
+
|
|
162
177
|
Core does not install an `at_exit` hook. Small scripts should call close from
|
|
163
178
|
their own shutdown path:
|
|
164
179
|
|
|
@@ -48,6 +48,13 @@ module Julewire
|
|
|
48
48
|
self
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
+
def before_fork!(timeout: nil)
|
|
52
|
+
return self unless @output.respond_to?(:before_fork!)
|
|
53
|
+
return false if @output.before_fork!(timeout: timeout) == false
|
|
54
|
+
|
|
55
|
+
self
|
|
56
|
+
end
|
|
57
|
+
|
|
51
58
|
def resource_identity = @output
|
|
52
59
|
|
|
53
60
|
private
|
|
@@ -9,6 +9,7 @@ module Julewire
|
|
|
9
9
|
@destinations = destinations.dup.freeze
|
|
10
10
|
@on_drop = on_drop
|
|
11
11
|
@on_failure = on_failure
|
|
12
|
+
@prepared_destinations = []
|
|
12
13
|
end
|
|
13
14
|
|
|
14
15
|
class << self
|
|
@@ -41,6 +42,21 @@ module Julewire
|
|
|
41
42
|
@destinations.each do |destination|
|
|
42
43
|
call_destination_after_fork(destination)
|
|
43
44
|
end
|
|
45
|
+
@prepared_destinations = []
|
|
46
|
+
self
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def before_fork!(timeout:)
|
|
50
|
+
Validation.validate_timeout!(timeout, name: :timeout)
|
|
51
|
+
return self unless @prepared_destinations.empty?
|
|
52
|
+
|
|
53
|
+
prepare_destinations_before_fork(timeout)
|
|
54
|
+
self
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def cancel_before_fork!
|
|
58
|
+
@prepared_destinations.reverse_each { call_destination_after_fork(it) }
|
|
59
|
+
@prepared_destinations = []
|
|
44
60
|
self
|
|
45
61
|
end
|
|
46
62
|
|
|
@@ -64,6 +80,23 @@ module Julewire
|
|
|
64
80
|
|
|
65
81
|
private
|
|
66
82
|
|
|
83
|
+
def prepare_destinations_before_fork(timeout)
|
|
84
|
+
deadline = Scheduling::Deadline.for(timeout)
|
|
85
|
+
prepared = []
|
|
86
|
+
@destinations.each do |destination|
|
|
87
|
+
next unless destination.respond_to?(:before_fork!)
|
|
88
|
+
|
|
89
|
+
remaining = Scheduling::Deadline.remaining(deadline)
|
|
90
|
+
prepared << destination
|
|
91
|
+
result = destination.before_fork!(timeout: remaining)
|
|
92
|
+
raise Error, "destination #{destination_name(destination)} rejected before_fork" if result == false
|
|
93
|
+
end
|
|
94
|
+
@prepared_destinations = prepared
|
|
95
|
+
rescue StandardError
|
|
96
|
+
prepared.reverse_each { call_destination_after_fork(it) }
|
|
97
|
+
raise
|
|
98
|
+
end
|
|
99
|
+
|
|
67
100
|
def call_lifecycle(method_name, timeout:, skip_resource_identities: nil)
|
|
68
101
|
Validation.validate_timeout!(timeout, name: :timeout)
|
|
69
102
|
call_lifecycle_safely(method_name, timeout, skip_resource_identities)
|
|
@@ -101,6 +134,8 @@ module Julewire
|
|
|
101
134
|
|
|
102
135
|
def call_destination_after_fork(destination)
|
|
103
136
|
destination.after_fork! if destination.respond_to?(:after_fork!)
|
|
137
|
+
rescue UnsafeForkError
|
|
138
|
+
raise
|
|
104
139
|
rescue StandardError => e
|
|
105
140
|
notify_failure(
|
|
106
141
|
e,
|
|
@@ -74,6 +74,8 @@ module Julewire
|
|
|
74
74
|
initialize_tracking
|
|
75
75
|
@output.after_fork!
|
|
76
76
|
self
|
|
77
|
+
rescue UnsafeForkError
|
|
78
|
+
raise
|
|
77
79
|
rescue StandardError => e
|
|
78
80
|
notify_failure(
|
|
79
81
|
e,
|
|
@@ -84,6 +86,12 @@ module Julewire
|
|
|
84
86
|
self
|
|
85
87
|
end
|
|
86
88
|
|
|
89
|
+
def before_fork!(timeout: nil)
|
|
90
|
+
return false if @output.before_fork!(timeout: timeout) == false
|
|
91
|
+
|
|
92
|
+
self
|
|
93
|
+
end
|
|
94
|
+
|
|
87
95
|
def resource_identity
|
|
88
96
|
@output.resource_identity
|
|
89
97
|
end
|
|
@@ -22,6 +22,17 @@ module Julewire
|
|
|
22
22
|
self
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
def before_fork!(timeout: nil)
|
|
26
|
+
result = @lifecycle_mutex.synchronize do
|
|
27
|
+
@mutex.synchronize do
|
|
28
|
+
@output.before_fork!(timeout: timeout) if @output.respond_to?(:before_fork!)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
return false if result == false
|
|
32
|
+
|
|
33
|
+
self
|
|
34
|
+
end
|
|
35
|
+
|
|
25
36
|
def output_class_name = @output.class.name
|
|
26
37
|
|
|
27
38
|
def resource_identity = @output
|
|
@@ -86,11 +86,28 @@ module Julewire
|
|
|
86
86
|
@mutex.synchronize { initialize_buffer }
|
|
87
87
|
@destination.after_fork! if @destination.respond_to?(:after_fork!)
|
|
88
88
|
self
|
|
89
|
+
rescue UnsafeForkError
|
|
90
|
+
raise
|
|
89
91
|
rescue StandardError => e
|
|
90
92
|
record_failure(e, nil, phase: :after_fork)
|
|
91
93
|
self
|
|
92
94
|
end
|
|
93
95
|
|
|
96
|
+
def before_fork!(timeout: nil)
|
|
97
|
+
return self unless @destination.respond_to?(:before_fork!)
|
|
98
|
+
|
|
99
|
+
Validation.validate_timeout!(timeout, name: :timeout)
|
|
100
|
+
deadline = Scheduling::Deadline.for(timeout)
|
|
101
|
+
unless flush(timeout: Scheduling::Deadline.remaining(deadline))
|
|
102
|
+
raise Error, "tail-sampling destination could not flush before fork"
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
result = @destination.before_fork!(timeout: Scheduling::Deadline.remaining(deadline))
|
|
106
|
+
return false if result == false
|
|
107
|
+
|
|
108
|
+
self
|
|
109
|
+
end
|
|
110
|
+
|
|
94
111
|
def resource_identity = self
|
|
95
112
|
|
|
96
113
|
def health
|
|
@@ -152,6 +152,11 @@ module Julewire
|
|
|
152
152
|
|
|
153
153
|
def labels = runtime.labels
|
|
154
154
|
def after_fork! = runtime.after_fork!
|
|
155
|
+
|
|
156
|
+
def before_fork!(timeout: nil)
|
|
157
|
+
runtime.before_fork!(timeout: timeout)
|
|
158
|
+
end
|
|
159
|
+
|
|
155
160
|
def reset! = runtime.reset_facade!
|
|
156
161
|
|
|
157
162
|
def close(timeout: UNSET)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "concurrent/map"
|
|
4
|
+
|
|
5
|
+
module Julewire
|
|
6
|
+
module Core
|
|
7
|
+
module Integration
|
|
8
|
+
module BeforeForkHooks
|
|
9
|
+
@entries = Concurrent::Map.new
|
|
10
|
+
|
|
11
|
+
class << self
|
|
12
|
+
def register(integration, component:, &callback)
|
|
13
|
+
raise ArgumentError, "block required" unless callback
|
|
14
|
+
|
|
15
|
+
HookNames.validate!(integration, name: :integration)
|
|
16
|
+
HookNames.validate!(component, name: :component)
|
|
17
|
+
entries[[integration, component]] = callback
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def run
|
|
21
|
+
entries.each_value(&:call)
|
|
22
|
+
nil
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
attr_reader :entries
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -15,8 +15,8 @@ module Julewire
|
|
|
15
15
|
def register(integration, component:, &callback)
|
|
16
16
|
raise ArgumentError, "block required" unless callback
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
HookNames.validate!(integration, name: :integration)
|
|
19
|
+
HookNames.validate!(component, name: :component)
|
|
20
20
|
register_entry(integration, component, callback)
|
|
21
21
|
end
|
|
22
22
|
|
|
@@ -43,11 +43,6 @@ module Julewire
|
|
|
43
43
|
component: entry.component
|
|
44
44
|
)
|
|
45
45
|
end
|
|
46
|
-
|
|
47
|
-
def validate_symbol_name!(value, name:)
|
|
48
|
-
raise TypeError, "#{name} must be a Symbol" unless value.instance_of?(Symbol)
|
|
49
|
-
raise ArgumentError, "#{name} is required" if value == :""
|
|
50
|
-
end
|
|
51
46
|
end
|
|
52
47
|
end
|
|
53
48
|
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Julewire
|
|
4
|
+
module Core
|
|
5
|
+
module Integration
|
|
6
|
+
module HookNames
|
|
7
|
+
class << self
|
|
8
|
+
def validate!(value, name:)
|
|
9
|
+
raise TypeError, "#{name} must be a Symbol" unless value.instance_of?(Symbol)
|
|
10
|
+
raise ArgumentError, "#{name} is required" if value == :""
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -15,6 +15,10 @@ module Julewire
|
|
|
15
15
|
def register_after_fork(integration, component:, &)
|
|
16
16
|
ForkHooks.register(integration, component: component, &)
|
|
17
17
|
end
|
|
18
|
+
|
|
19
|
+
def register_before_fork(integration, component:, &)
|
|
20
|
+
BeforeForkHooks.register(integration, component: component, &)
|
|
21
|
+
end
|
|
18
22
|
end
|
|
19
23
|
end
|
|
20
24
|
end
|
|
@@ -155,6 +155,19 @@ module Julewire
|
|
|
155
155
|
RuntimeRegistry.reset_after_fork(primary: self)
|
|
156
156
|
end
|
|
157
157
|
|
|
158
|
+
def before_fork!(timeout: nil)
|
|
159
|
+
reject_runtime_call_during_configure!(:before_fork!)
|
|
160
|
+
RuntimeRegistry.prepare_before_fork(primary: self, timeout: timeout)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def before_fork_runtime!(timeout:)
|
|
164
|
+
runtime_state.pipeline.before_fork!(timeout: timeout)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def cancel_before_fork_runtime!
|
|
168
|
+
runtime_state.pipeline.cancel_before_fork!
|
|
169
|
+
end
|
|
170
|
+
|
|
158
171
|
def reset_after_fork_runtime!
|
|
159
172
|
reset_after_fork_state!
|
|
160
173
|
runtime_state.pipeline.after_fork!
|
|
@@ -47,6 +47,22 @@ module Julewire
|
|
|
47
47
|
runtimes.each(&:reset_after_fork_runtime!)
|
|
48
48
|
Integration::ForkHooks.run
|
|
49
49
|
end
|
|
50
|
+
|
|
51
|
+
def prepare_before_fork(primary:, timeout:)
|
|
52
|
+
Validation.validate_timeout!(timeout, name: :timeout)
|
|
53
|
+
runtimes = [primary] + @runtimes.get.values
|
|
54
|
+
deadline = Scheduling::Deadline.for(timeout)
|
|
55
|
+
|
|
56
|
+
begin
|
|
57
|
+
runtimes.each do |runtime|
|
|
58
|
+
runtime.before_fork_runtime!(timeout: Scheduling::Deadline.remaining(deadline))
|
|
59
|
+
end
|
|
60
|
+
Integration::BeforeForkHooks.run
|
|
61
|
+
rescue StandardError
|
|
62
|
+
runtimes.reverse_each(&:cancel_before_fork_runtime!)
|
|
63
|
+
raise
|
|
64
|
+
end
|
|
65
|
+
end
|
|
50
66
|
end
|
|
51
67
|
end
|
|
52
68
|
end
|
data/lib/julewire/core.rb
CHANGED
|
@@ -65,6 +65,7 @@ module Julewire
|
|
|
65
65
|
Tail = Core::Diagnostics::Tail
|
|
66
66
|
TailSampling = Core::Destinations::TailSampling
|
|
67
67
|
TextEncoder = Core::Serialization::TextEncoder
|
|
68
|
+
UnsafeForkError = Core::UnsafeForkError
|
|
68
69
|
|
|
69
70
|
Core::Processing.register(:sampling) do |rate:, key: nil|
|
|
70
71
|
Core::Processing::Sampling.head(rate: rate, key: key)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: julewire-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1.
|
|
4
|
+
version: 1.1.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alexander Grebennik
|
|
@@ -132,12 +132,14 @@ files:
|
|
|
132
132
|
- lib/julewire/core/fields/stack_set.rb
|
|
133
133
|
- lib/julewire/core/fields/static_labels.rb
|
|
134
134
|
- lib/julewire/core/fields/summary_proxy.rb
|
|
135
|
+
- lib/julewire/core/integration/before_fork_hooks.rb
|
|
135
136
|
- lib/julewire/core/integration/configurable.rb
|
|
136
137
|
- lib/julewire/core/integration/destination_health.rb
|
|
137
138
|
- lib/julewire/core/integration/event_subscriber.rb
|
|
138
139
|
- lib/julewire/core/integration/facade.rb
|
|
139
140
|
- lib/julewire/core/integration/fork_hooks.rb
|
|
140
141
|
- lib/julewire/core/integration/health.rb
|
|
142
|
+
- lib/julewire/core/integration/hook_names.rb
|
|
141
143
|
- lib/julewire/core/integration/ivar_state.rb
|
|
142
144
|
- lib/julewire/core/integration/lifecycle.rb
|
|
143
145
|
- lib/julewire/core/integration/protocol.rb
|
|
@@ -194,6 +196,7 @@ files:
|
|
|
194
196
|
- lib/julewire/core/serialization/value_copy.rb
|
|
195
197
|
- lib/julewire/core/serialization/value_traversal.rb
|
|
196
198
|
- lib/julewire/core/testing.rb
|
|
199
|
+
- lib/julewire/core/unsafe_fork_error.rb
|
|
197
200
|
- lib/julewire/core/validation.rb
|
|
198
201
|
- lib/julewire/core/version.rb
|
|
199
202
|
- lib/julewire/error.rb
|