einhorn 0.8.2 → 1.0.1
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/Changes.md +15 -0
- data/README.md +7 -38
- data/einhorn.gemspec +23 -21
- data/example/pool_worker.rb +2 -2
- data/example/thin_example +8 -8
- data/example/time_server +5 -5
- data/lib/einhorn/client.rb +8 -8
- data/lib/einhorn/command/interface.rb +92 -98
- data/lib/einhorn/command.rb +75 -85
- data/lib/einhorn/compat.rb +7 -7
- data/lib/einhorn/event/abstract_text_descriptor.rb +32 -36
- data/lib/einhorn/event/ack_timer.rb +2 -2
- data/lib/einhorn/event/command_server.rb +7 -9
- data/lib/einhorn/event/connection.rb +1 -3
- data/lib/einhorn/event/loop_breaker.rb +2 -1
- data/lib/einhorn/event/persistent.rb +2 -2
- data/lib/einhorn/event/timer.rb +4 -4
- data/lib/einhorn/event.rb +20 -20
- data/lib/einhorn/prctl.rb +2 -2
- data/lib/einhorn/prctl_linux.rb +13 -14
- data/lib/einhorn/safe_yaml.rb +17 -0
- data/lib/einhorn/version.rb +1 -1
- data/lib/einhorn/worker.rb +26 -30
- data/lib/einhorn/worker_pool.rb +9 -9
- data/lib/einhorn.rb +120 -125
- metadata +37 -110
- data/.gitignore +0 -17
- data/.travis.yml +0 -10
- data/CONTRIBUTORS +0 -6
- data/Gemfile +0 -11
- data/History.txt +0 -4
- data/README.md.in +0 -94
- data/Rakefile +0 -27
- data/test/_lib.rb +0 -12
- data/test/integration/_lib/fixtures/env_printer/env_printer.rb +0 -26
- data/test/integration/_lib/fixtures/exit_during_upgrade/exiting_server.rb +0 -23
- data/test/integration/_lib/fixtures/exit_during_upgrade/upgrade_reexec.rb +0 -6
- data/test/integration/_lib/fixtures/pdeathsig_printer/pdeathsig_printer.rb +0 -29
- data/test/integration/_lib/fixtures/signal_timeout/sleepy_server.rb +0 -23
- data/test/integration/_lib/fixtures/upgrade_project/upgrading_server.rb +0 -24
- data/test/integration/_lib/helpers/einhorn_helpers.rb +0 -148
- data/test/integration/_lib/helpers.rb +0 -4
- data/test/integration/_lib.rb +0 -6
- data/test/integration/pdeathsig.rb +0 -26
- data/test/integration/startup.rb +0 -31
- data/test/integration/upgrading.rb +0 -204
- data/test/unit/_lib/bad_worker.rb +0 -7
- data/test/unit/_lib/sleep_worker.rb +0 -5
- data/test/unit/einhorn/client.rb +0 -88
- data/test/unit/einhorn/command/interface.rb +0 -49
- data/test/unit/einhorn/command.rb +0 -135
- data/test/unit/einhorn/event.rb +0 -89
- data/test/unit/einhorn/worker_pool.rb +0 -39
- data/test/unit/einhorn.rb +0 -96
- /data/{LICENSE → LICENSE.txt} +0 -0
data/lib/einhorn/event/timer.rb
CHANGED
@@ -2,7 +2,7 @@ module Einhorn::Event
|
|
2
2
|
class Timer
|
3
3
|
attr_reader :time
|
4
4
|
|
5
|
-
def initialize(time, start=nil, &blk)
|
5
|
+
def initialize(time, start = nil, &blk)
|
6
6
|
@time = time
|
7
7
|
@start = start || Time.now
|
8
8
|
@blk = blk
|
@@ -10,7 +10,7 @@ module Einhorn::Event
|
|
10
10
|
|
11
11
|
# TODO: abstract into some interface
|
12
12
|
def self.open(*args, &blk)
|
13
|
-
instance =
|
13
|
+
instance = new(*args, &blk)
|
14
14
|
instance.register!
|
15
15
|
instance
|
16
16
|
end
|
@@ -27,12 +27,12 @@ module Einhorn::Event
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def register!
|
30
|
-
Einhorn.log_debug("Scheduling a new #{
|
30
|
+
Einhorn.log_debug("Scheduling a new #{time}s timer")
|
31
31
|
Einhorn::Event.register_timer(self)
|
32
32
|
end
|
33
33
|
|
34
34
|
def deregister!
|
35
|
-
Einhorn.log_debug("Nuking timer that expired #{Time.now -
|
35
|
+
Einhorn.log_debug("Nuking timer that expired #{Time.now - expires_at}s ago")
|
36
36
|
Einhorn::Event.deregister_timer(self)
|
37
37
|
end
|
38
38
|
end
|
data/lib/einhorn/event.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "set"
|
2
2
|
|
3
3
|
module Einhorn
|
4
4
|
module Event
|
@@ -37,8 +37,8 @@ module Einhorn
|
|
37
37
|
|
38
38
|
def self.persistent_descriptors
|
39
39
|
descriptor_sets = @@readable.values + @@writeable.values + @@timers.values
|
40
|
-
descriptors = descriptor_sets.inject {|a, b| a | b}
|
41
|
-
descriptors.select {|descriptor| Einhorn::Event::Persistent.persistent?(descriptor)}
|
40
|
+
descriptors = descriptor_sets.inject { |a, b| a | b }
|
41
|
+
descriptors.select { |descriptor| Einhorn::Event::Persistent.persistent?(descriptor) }
|
42
42
|
end
|
43
43
|
|
44
44
|
def self.restore_persistent_descriptors(persistent_descriptors)
|
@@ -81,8 +81,8 @@ module Einhorn
|
|
81
81
|
|
82
82
|
def self.writeable_fds
|
83
83
|
writers = @@writeable.select do |io, writers|
|
84
|
-
writers.any? {|writer| writer.write_pending?}
|
85
|
-
end.map {|io, writers| io}
|
84
|
+
writers.any? { |writer| writer.write_pending? }
|
85
|
+
end.map { |io, writers| io }
|
86
86
|
Einhorn.log_debug("Writeable fds are #{writers.inspect}")
|
87
87
|
writers
|
88
88
|
end
|
@@ -118,7 +118,7 @@ module Einhorn
|
|
118
118
|
|
119
119
|
def self.timeout
|
120
120
|
# (expires_at of the next timer) - now
|
121
|
-
if expires_at = @@timers.keys.
|
121
|
+
if (expires_at = @@timers.keys.min)
|
122
122
|
expires_at - Time.now
|
123
123
|
else
|
124
124
|
@@default_timeout
|
@@ -130,7 +130,7 @@ module Einhorn
|
|
130
130
|
# handlers. Since it's just an array we push to/shift from, we
|
131
131
|
# can be sure there's no race (such as adding hash keys during
|
132
132
|
# iteration.)
|
133
|
-
while blk = @@signal_actions.shift
|
133
|
+
while (blk = @@signal_actions.shift)
|
134
134
|
blk.call
|
135
135
|
end
|
136
136
|
end
|
@@ -143,32 +143,32 @@ module Einhorn
|
|
143
143
|
|
144
144
|
readable, writeable, _ = IO.select(readable_fds, writeable_fds, nil, time)
|
145
145
|
(readable || []).each do |io|
|
146
|
-
@@readable[io].each {|reader| reader.notify_readable}
|
146
|
+
@@readable[io].each { |reader| reader.notify_readable }
|
147
147
|
end
|
148
148
|
|
149
149
|
(writeable || []).each do |io|
|
150
|
-
@@writeable[io].each {|writer| writer.notify_writeable}
|
150
|
+
@@writeable[io].each { |writer| writer.notify_writeable }
|
151
151
|
end
|
152
152
|
end
|
153
153
|
|
154
154
|
def self.run_timers
|
155
|
-
@@timers.select {|expires_at, _| expires_at <= Time.now}.each do |expires_at, timers|
|
155
|
+
@@timers.select { |expires_at, _| expires_at <= Time.now }.each do |expires_at, timers|
|
156
156
|
# Going to be modifying the set, so let's dup it.
|
157
|
-
timers.dup.each {|timer| timer.ring!}
|
157
|
+
timers.dup.each { |timer| timer.ring! }
|
158
158
|
end
|
159
159
|
end
|
160
160
|
|
161
161
|
def self.break_loop
|
162
162
|
Einhorn.log_debug("Breaking the loop")
|
163
163
|
begin
|
164
|
-
@@loopbreak_writer.write_nonblock(
|
164
|
+
@@loopbreak_writer.write_nonblock("a")
|
165
165
|
rescue Errno::EWOULDBLOCK, Errno::EAGAIN
|
166
166
|
Einhorn.log_error("Loop break pipe is full -- probably means that we are quite backlogged")
|
167
167
|
end
|
168
168
|
end
|
169
169
|
|
170
170
|
def self.default_timeout=(val)
|
171
|
-
@@default_timeout = val.to_i == 0 ? nil : val.to_i
|
171
|
+
@@default_timeout = (val.to_i == 0) ? nil : val.to_i
|
172
172
|
end
|
173
173
|
|
174
174
|
def self.default_timeout
|
@@ -177,11 +177,11 @@ module Einhorn
|
|
177
177
|
end
|
178
178
|
end
|
179
179
|
|
180
|
-
require
|
181
|
-
require
|
180
|
+
require "einhorn/event/persistent"
|
181
|
+
require "einhorn/event/timer"
|
182
182
|
|
183
|
-
require
|
184
|
-
require
|
185
|
-
require
|
186
|
-
require
|
187
|
-
require
|
183
|
+
require "einhorn/event/abstract_text_descriptor"
|
184
|
+
require "einhorn/event/ack_timer"
|
185
|
+
require "einhorn/event/command_server"
|
186
|
+
require "einhorn/event/connection"
|
187
|
+
require "einhorn/event/loop_breaker"
|
data/lib/einhorn/prctl.rb
CHANGED
@@ -13,9 +13,9 @@ module Einhorn
|
|
13
13
|
# Deliberately empty; NotImplementedError is intended
|
14
14
|
end
|
15
15
|
|
16
|
-
if RUBY_PLATFORM
|
16
|
+
if RUBY_PLATFORM.match?(/linux/)
|
17
17
|
begin
|
18
|
-
require
|
18
|
+
require "einhorn/prctl_linux"
|
19
19
|
Prctl = PrctlLinux
|
20
20
|
rescue LoadError
|
21
21
|
Prctl = PrctlUnimplemented
|
data/lib/einhorn/prctl_linux.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "fiddle"
|
2
|
+
require "fiddle/import"
|
3
3
|
|
4
4
|
module Einhorn
|
5
5
|
module PrctlRaw
|
6
6
|
extend Fiddle::Importer
|
7
7
|
dlload Fiddle.dlopen(nil) # libc
|
8
|
-
extern
|
8
|
+
extern "int prctl(int, unsigned long, unsigned long, unsigned long, unsigned long)"
|
9
9
|
|
10
10
|
# From linux/prctl.h
|
11
11
|
SET_PDEATHSIG = 1
|
@@ -14,34 +14,33 @@ module Einhorn
|
|
14
14
|
|
15
15
|
class PrctlLinux < PrctlAbstract
|
16
16
|
# Reading integers is hard with fiddle. :(
|
17
|
-
IntStruct = Fiddle::CStructBuilder.create(Fiddle::CStruct, [Fiddle::TYPE_INT], [
|
17
|
+
IntStruct = Fiddle::CStructBuilder.create(Fiddle::CStruct, [Fiddle::TYPE_INT], ["i"])
|
18
18
|
|
19
19
|
def self.get_pdeathsig
|
20
20
|
out = IntStruct.malloc
|
21
21
|
out.i = 0
|
22
|
-
if PrctlRaw.prctl(PrctlRaw::GET_PDEATHSIG, out.to_i, 0, 0, 0) != 0
|
22
|
+
if PrctlRaw.prctl(PrctlRaw::GET_PDEATHSIG, out.to_i, 0, 0, 0) != 0
|
23
23
|
raise SystemCallError.new("get_pdeathsig", Fiddle.last_error)
|
24
24
|
end
|
25
25
|
|
26
26
|
signo = out.i
|
27
|
-
if signo == 0
|
27
|
+
if signo == 0
|
28
28
|
return nil
|
29
29
|
end
|
30
30
|
|
31
|
-
|
31
|
+
Signal.signame(signo)
|
32
32
|
end
|
33
33
|
|
34
34
|
def self.set_pdeathsig(signal)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
signo = Signal.list.fetch(signal)
|
35
|
+
signo = if signal.nil?
|
36
|
+
0
|
37
|
+
elsif signal.instance_of?(String)
|
38
|
+
Signal.list.fetch(signal)
|
40
39
|
else
|
41
|
-
|
40
|
+
signal
|
42
41
|
end
|
43
42
|
|
44
|
-
if PrctlRaw.prctl(PrctlRaw::SET_PDEATHSIG, signo, 0, 0, 0) != 0
|
43
|
+
if PrctlRaw.prctl(PrctlRaw::SET_PDEATHSIG, signo, 0, 0, 0) != 0
|
45
44
|
raise SystemCallError.new("set_pdeathsig(#{signal})", Fiddle.last_error)
|
46
45
|
end
|
47
46
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "yaml"
|
2
|
+
|
3
|
+
module Einhorn
|
4
|
+
module SafeYAML
|
5
|
+
begin
|
6
|
+
YAML.safe_load("---", permitted_classes: [])
|
7
|
+
rescue ArgumentError
|
8
|
+
def self.load(payload)
|
9
|
+
YAML.safe_load(payload, [Set, Symbol, Time], [], true)
|
10
|
+
end
|
11
|
+
else
|
12
|
+
def self.load(payload) # rubocop:disable Lint/DuplicateMethods
|
13
|
+
YAML.safe_load(payload, permitted_classes: [Set, Symbol, Time], aliases: true)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/einhorn/version.rb
CHANGED
data/lib/einhorn/worker.rb
CHANGED
@@ -1,23 +1,21 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "einhorn/client"
|
2
|
+
require "einhorn/command/interface"
|
3
3
|
|
4
4
|
module Einhorn
|
5
5
|
module Worker
|
6
6
|
class WorkerError < RuntimeError; end
|
7
7
|
|
8
8
|
def self.is_worker?
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
true
|
15
|
-
end
|
9
|
+
ensure_worker!
|
10
|
+
rescue WorkerError
|
11
|
+
false
|
12
|
+
else
|
13
|
+
true
|
16
14
|
end
|
17
15
|
|
18
16
|
def self.ensure_worker!
|
19
17
|
# Make sure that EINHORN_MASTER_PID is my parent
|
20
|
-
if ppid_s = ENV[
|
18
|
+
if (ppid_s = ENV["EINHORN_MASTER_PID"])
|
21
19
|
ppid = ppid_s.to_i
|
22
20
|
raise WorkerError.new("EINHORN_MASTER_PID environment variable is #{ppid_s.inspect}, but my parent's pid is #{Process.ppid.inspect}. This probably means that I am a subprocess of an Einhorn worker, but am not one myself.") unless Process.ppid == ppid
|
23
21
|
true
|
@@ -27,10 +25,8 @@ module Einhorn
|
|
27
25
|
end
|
28
26
|
|
29
27
|
def self.ack(*args)
|
30
|
-
|
31
|
-
|
32
|
-
rescue WorkerError
|
33
|
-
end
|
28
|
+
ack!(*args)
|
29
|
+
rescue WorkerError
|
34
30
|
end
|
35
31
|
|
36
32
|
# Returns the index of this Einhorn child process.
|
@@ -42,7 +38,7 @@ module Einhorn
|
|
42
38
|
# Returns nil if not running in Einhorn, or running on a version
|
43
39
|
# of Einhorn that does not support indexing children.
|
44
40
|
def self.einhorn_child_index
|
45
|
-
index = ENV[
|
41
|
+
index = ENV["EINHORN_CHILD_INDEX"]
|
46
42
|
if index.nil? || index !~ /\A \d+ \z/x
|
47
43
|
index
|
48
44
|
else
|
@@ -65,9 +61,9 @@ module Einhorn
|
|
65
61
|
# TODO: add a :fileno option? Easy to implement; not sure if it'd
|
66
62
|
# be useful for anything. Maybe if it's always fd 3, because then
|
67
63
|
# the user wouldn't have to provide an arg.
|
68
|
-
def self.ack!(discovery
|
64
|
+
def self.ack!(discovery = :env, arg = nil)
|
69
65
|
handle_command_socket(discovery, arg) do |client|
|
70
|
-
client.send_command(
|
66
|
+
client.send_command("command" => "worker:ack", "pid" => $$)
|
71
67
|
end
|
72
68
|
end
|
73
69
|
|
@@ -84,21 +80,21 @@ module Einhorn
|
|
84
80
|
# Then @arg being true causes the FD to be left open after ACK;
|
85
81
|
# otherwise it is closed.
|
86
82
|
# :direct: Provide the path to the command socket in @arg.
|
87
|
-
def self.ping!(request_id, discovery
|
83
|
+
def self.ping!(request_id, discovery = :env, arg = nil)
|
88
84
|
handle_command_socket(discovery, arg) do |client|
|
89
|
-
client.send_command(
|
85
|
+
client.send_command("command" => "worker:ping", "pid" => $$, "request_id" => request_id)
|
90
86
|
end
|
91
87
|
end
|
92
88
|
|
93
|
-
def self.socket(number=nil)
|
89
|
+
def self.socket(number = nil)
|
94
90
|
number ||= 0
|
95
91
|
einhorn_fd(number)
|
96
92
|
end
|
97
93
|
|
98
|
-
def self.socket!(number=nil)
|
94
|
+
def self.socket!(number = nil)
|
99
95
|
number ||= 0
|
100
96
|
|
101
|
-
unless count = einhorn_fd_count
|
97
|
+
unless (count = einhorn_fd_count)
|
102
98
|
raise "No EINHORN_FD_COUNT provided in environment. Are you running under Einhorn?"
|
103
99
|
end
|
104
100
|
|
@@ -106,7 +102,7 @@ module Einhorn
|
|
106
102
|
raise "Only #{count} FDs available, but FD #{number} was requested"
|
107
103
|
end
|
108
104
|
|
109
|
-
unless fd = einhorn_fd(number)
|
105
|
+
unless (fd = einhorn_fd(number))
|
110
106
|
raise "No EINHORN_FD_#{number} provided in environment. That's pretty weird"
|
111
107
|
end
|
112
108
|
|
@@ -114,14 +110,14 @@ module Einhorn
|
|
114
110
|
end
|
115
111
|
|
116
112
|
def self.einhorn_fd(n)
|
117
|
-
unless raw_fd = ENV["EINHORN_FD_#{n}"]
|
113
|
+
unless (raw_fd = ENV["EINHORN_FD_#{n}"])
|
118
114
|
return nil
|
119
115
|
end
|
120
116
|
Integer(raw_fd)
|
121
117
|
end
|
122
118
|
|
123
119
|
def self.einhorn_fd_count
|
124
|
-
unless raw_count = ENV[
|
120
|
+
unless (raw_count = ENV["EINHORN_FD_COUNT"])
|
125
121
|
return 0
|
126
122
|
end
|
127
123
|
Integer(raw_count)
|
@@ -129,21 +125,19 @@ module Einhorn
|
|
129
125
|
|
130
126
|
# Call this to handle graceful shutdown requests to your app.
|
131
127
|
def self.graceful_shutdown(&blk)
|
132
|
-
Signal.trap(
|
128
|
+
Signal.trap("USR2", &blk)
|
133
129
|
end
|
134
130
|
|
135
|
-
private
|
136
|
-
|
137
131
|
def self.handle_command_socket(discovery, contextual_arg)
|
138
132
|
ensure_worker!
|
139
133
|
close_after_use = true
|
140
134
|
|
141
135
|
case discovery
|
142
136
|
when :env
|
143
|
-
socket = ENV[
|
137
|
+
socket = ENV["EINHORN_SOCK_PATH"]
|
144
138
|
client = Einhorn::Client.for_path(socket)
|
145
139
|
when :fd
|
146
|
-
raise "No EINHORN_SOCK_FD provided in environment. Did you run einhorn with the -g flag?" unless fd_str = ENV[
|
140
|
+
raise "No EINHORN_SOCK_FD provided in environment. Did you run einhorn with the -g flag?" unless (fd_str = ENV["EINHORN_SOCK_FD"])
|
147
141
|
|
148
142
|
fd = Integer(fd_str)
|
149
143
|
client = Einhorn::Client.for_fd(fd)
|
@@ -160,11 +154,13 @@ module Einhorn
|
|
160
154
|
|
161
155
|
true
|
162
156
|
end
|
157
|
+
private_class_method :handle_command_socket
|
163
158
|
|
164
159
|
def self.socket_from_filesystem(cmd_name)
|
165
160
|
ppid = Process.ppid
|
166
161
|
socket_path_file = Einhorn::Command::Interface.socket_path_file(ppid)
|
167
162
|
File.read(socket_path_file)
|
168
163
|
end
|
164
|
+
private_class_method :socket_from_filesystem
|
169
165
|
end
|
170
166
|
end
|
data/lib/einhorn/worker_pool.rb
CHANGED
@@ -7,13 +7,13 @@ module Einhorn
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def self.workers
|
10
|
-
workers_with_state.map {|pid, _| pid}
|
10
|
+
workers_with_state.map { |pid, _| pid }
|
11
11
|
end
|
12
12
|
|
13
13
|
def self.unsignaled_workers
|
14
14
|
workers_with_state.select do |pid, spec|
|
15
15
|
spec[:signaled].length == 0
|
16
|
-
end.map {|pid, _| pid}
|
16
|
+
end.map { |pid, _| pid }
|
17
17
|
end
|
18
18
|
|
19
19
|
def self.modern_workers_with_state
|
@@ -23,15 +23,15 @@ module Einhorn
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def self.acked_modern_workers_with_state
|
26
|
-
modern_workers_with_state.select {|pid, spec| spec[:acked]}
|
26
|
+
modern_workers_with_state.select { |pid, spec| spec[:acked] }
|
27
27
|
end
|
28
28
|
|
29
29
|
def self.modern_workers
|
30
|
-
modern_workers_with_state.map {|pid, _| pid}
|
30
|
+
modern_workers_with_state.map { |pid, _| pid }
|
31
31
|
end
|
32
32
|
|
33
33
|
def self.acked_modern_workers
|
34
|
-
acked_modern_workers_with_state.map {|pid, _| pid}
|
34
|
+
acked_modern_workers_with_state.map { |pid, _| pid }
|
35
35
|
end
|
36
36
|
|
37
37
|
def self.unsignaled_modern_workers_with_state
|
@@ -43,23 +43,23 @@ module Einhorn
|
|
43
43
|
def self.acked_unsignaled_modern_workers
|
44
44
|
acked_modern_workers_with_state.select do |_, spec|
|
45
45
|
spec[:signaled].length == 0
|
46
|
-
end.map {|pid, _| pid}
|
46
|
+
end.map { |pid, _| pid }
|
47
47
|
end
|
48
48
|
|
49
49
|
def self.unsignaled_modern_workers_with_priority
|
50
50
|
unsignaled_modern_workers_with_state.sort_by do |pid, spec|
|
51
51
|
spec[:acked] ? 1 : 0
|
52
|
-
end.map {|pid, _| pid}
|
52
|
+
end.map { |pid, _| pid }
|
53
53
|
end
|
54
54
|
|
55
55
|
def self.unacked_unsignaled_modern_workers_with_state
|
56
|
-
modern_workers_with_state.select {|pid, spec|
|
56
|
+
modern_workers_with_state.select { |pid, spec|
|
57
57
|
!spec[:acked] && spec[:signaled].length == 0
|
58
58
|
}
|
59
59
|
end
|
60
60
|
|
61
61
|
def self.unacked_unsignaled_modern_workers
|
62
|
-
unacked_unsignaled_modern_workers_with_state.map {|pid, _| pid}
|
62
|
+
unacked_unsignaled_modern_workers_with_state.map { |pid, _| pid }
|
63
63
|
end
|
64
64
|
|
65
65
|
# Use the number of modern workers, rather than unsignaled modern
|