einhorn 0.7.4 → 1.0.0

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.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/Changes.md +10 -0
  3. data/README.md +36 -30
  4. data/bin/einhorn +17 -2
  5. data/einhorn.gemspec +23 -21
  6. data/example/pool_worker.rb +1 -1
  7. data/example/thin_example +8 -8
  8. data/example/time_server +5 -5
  9. data/lib/einhorn/client.rb +8 -9
  10. data/lib/einhorn/command/interface.rb +100 -95
  11. data/lib/einhorn/command.rb +167 -88
  12. data/lib/einhorn/compat.rb +7 -7
  13. data/lib/einhorn/event/abstract_text_descriptor.rb +31 -35
  14. data/lib/einhorn/event/ack_timer.rb +2 -2
  15. data/lib/einhorn/event/command_server.rb +7 -9
  16. data/lib/einhorn/event/connection.rb +1 -3
  17. data/lib/einhorn/event/loop_breaker.rb +2 -1
  18. data/lib/einhorn/event/persistent.rb +2 -2
  19. data/lib/einhorn/event/timer.rb +4 -4
  20. data/lib/einhorn/event.rb +29 -20
  21. data/lib/einhorn/prctl.rb +26 -0
  22. data/lib/einhorn/prctl_linux.rb +48 -0
  23. data/lib/einhorn/safe_yaml.rb +17 -0
  24. data/lib/einhorn/version.rb +1 -1
  25. data/lib/einhorn/worker.rb +67 -49
  26. data/lib/einhorn/worker_pool.rb +9 -9
  27. data/lib/einhorn.rb +155 -126
  28. metadata +42 -137
  29. data/.gitignore +0 -17
  30. data/.travis.yml +0 -10
  31. data/CONTRIBUTORS +0 -6
  32. data/Gemfile +0 -11
  33. data/History.txt +0 -4
  34. data/README.md.in +0 -76
  35. data/Rakefile +0 -27
  36. data/test/_lib.rb +0 -12
  37. data/test/integration/_lib/fixtures/env_printer/env_printer.rb +0 -26
  38. data/test/integration/_lib/fixtures/exit_during_upgrade/exiting_server.rb +0 -22
  39. data/test/integration/_lib/fixtures/exit_during_upgrade/upgrade_reexec.rb +0 -6
  40. data/test/integration/_lib/fixtures/upgrade_project/upgrading_server.rb +0 -22
  41. data/test/integration/_lib/helpers/einhorn_helpers.rb +0 -143
  42. data/test/integration/_lib/helpers.rb +0 -4
  43. data/test/integration/_lib.rb +0 -6
  44. data/test/integration/startup.rb +0 -31
  45. data/test/integration/upgrading.rb +0 -157
  46. data/test/unit/einhorn/client.rb +0 -88
  47. data/test/unit/einhorn/command/interface.rb +0 -49
  48. data/test/unit/einhorn/command.rb +0 -21
  49. data/test/unit/einhorn/event.rb +0 -89
  50. data/test/unit/einhorn/worker_pool.rb +0 -39
  51. data/test/unit/einhorn.rb +0 -58
  52. /data/{LICENSE → LICENSE.txt} +0 -0
@@ -2,7 +2,7 @@ module Einhorn::Event
2
2
  class ACKTimer < Timer
3
3
  include Persistent
4
4
 
5
- def initialize(time, pid, start=nil)
5
+ def initialize(time, pid, start = nil)
6
6
  super(time, start) do
7
7
  Einhorn::Command.register_timer_ack(time, pid)
8
8
  end
@@ -10,7 +10,7 @@ module Einhorn::Event
10
10
  end
11
11
 
12
12
  def to_state
13
- {:class => self.class.to_s, :time => @time, :start => @start, :pid => @pid}
13
+ {class: self.class.to_s, time: @time, start: @start, pid: @pid}
14
14
  end
15
15
 
16
16
  def self.from_state(state)
@@ -3,7 +3,7 @@ module Einhorn::Event
3
3
  include Persistent
4
4
 
5
5
  def self.open(server)
6
- self.new(server)
6
+ new(server)
7
7
  end
8
8
 
9
9
  def initialize(server)
@@ -15,14 +15,12 @@ module Einhorn::Event
15
15
  end
16
16
 
17
17
  def notify_readable
18
- begin
19
- while true
20
- return if @closed
21
- sock = Einhorn::Compat.accept_nonblock(@server)
22
- Connection.open(sock)
23
- end
24
- rescue Errno::EAGAIN
18
+ loop do
19
+ return if @closed
20
+ sock = Einhorn::Compat.accept_nonblock(@server)
21
+ Connection.open(sock)
25
22
  end
23
+ rescue Errno::EAGAIN
26
24
  end
27
25
 
28
26
  def to_io
@@ -30,7 +28,7 @@ module Einhorn::Event
30
28
  end
31
29
 
32
30
  def to_state
33
- {:class => self.class.to_s, :server => @server.fileno}
31
+ {class: self.class.to_s, server: @server.fileno}
34
32
  end
35
33
 
36
34
  def self.from_state(state)
@@ -11,8 +11,6 @@ module Einhorn::Event
11
11
  split = @read_buffer.split("\n", 2)
12
12
  if split.length > 1
13
13
  split
14
- else
15
- nil
16
14
  end
17
15
  end
18
16
 
@@ -21,7 +19,7 @@ module Einhorn::Event
21
19
  end
22
20
 
23
21
  def to_state
24
- state = {:class => self.class.to_s, :socket => @socket.fileno}
22
+ state = {class: self.class.to_s, socket: @socket.fileno}
25
23
  # Don't include by default because it's not that pretty
26
24
  state[:read_buffer] = @read_buffer if @read_buffer.length > 0
27
25
  state[:write_buffer] = @write_buffer if @write_buffer.length > 0
@@ -1,6 +1,7 @@
1
1
  # TODO: set lots of cloexecs
2
2
  module Einhorn::Event
3
3
  class LoopBreaker < AbstractTextDescriptor
4
- def consume_record(record); end
4
+ def consume_record(record)
5
+ end
5
6
  end
6
7
  end
@@ -8,7 +8,7 @@ module Einhorn::Event
8
8
 
9
9
  def self.from_state(state)
10
10
  klass_name = state[:class]
11
- if klass = @@persistent[klass_name]
11
+ if (klass = @@persistent[klass_name])
12
12
  klass.from_state(state)
13
13
  else
14
14
  Einhorn.log_error("Unrecognized persistent descriptor class #{klass_name.inspect}. Ignoring. This most likely indicates that your Einhorn version has upgraded. Everything should still be working, but it may be worth a restart.", :upgrade)
@@ -17,7 +17,7 @@ module Einhorn::Event
17
17
  end
18
18
 
19
19
  def self.persistent?(descriptor)
20
- @@persistent.values.any? {|klass| descriptor.kind_of?(klass)}
20
+ @@persistent.values.any? { |klass| descriptor.is_a?(klass) }
21
21
  end
22
22
  end
23
23
  end
@@ -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 = self.new(*args, &blk)
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 #{self.time}s timer")
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 - self.expires_at}s ago")
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,9 +1,10 @@
1
- require 'set'
1
+ require "set"
2
2
 
3
3
  module Einhorn
4
4
  module Event
5
5
  @@loopbreak_reader = nil
6
6
  @@loopbreak_writer = nil
7
+ @@default_timeout = nil
7
8
  @@signal_actions = []
8
9
  @@readable = {}
9
10
  @@writeable = {}
@@ -36,8 +37,8 @@ module Einhorn
36
37
 
37
38
  def self.persistent_descriptors
38
39
  descriptor_sets = @@readable.values + @@writeable.values + @@timers.values
39
- descriptors = descriptor_sets.inject {|a, b| a | b}
40
- 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) }
41
42
  end
42
43
 
43
44
  def self.restore_persistent_descriptors(persistent_descriptors)
@@ -80,8 +81,8 @@ module Einhorn
80
81
 
81
82
  def self.writeable_fds
82
83
  writers = @@writeable.select do |io, writers|
83
- writers.any? {|writer| writer.write_pending?}
84
- end.map {|io, writers| io}
84
+ writers.any? { |writer| writer.write_pending? }
85
+ end.map { |io, writers| io }
85
86
  Einhorn.log_debug("Writeable fds are #{writers.inspect}")
86
87
  writers
87
88
  end
@@ -117,10 +118,10 @@ module Einhorn
117
118
 
118
119
  def self.timeout
119
120
  # (expires_at of the next timer) - now
120
- if expires_at = @@timers.keys.sort[0]
121
+ if (expires_at = @@timers.keys.min)
121
122
  expires_at - Time.now
122
123
  else
123
- nil
124
+ @@default_timeout
124
125
  end
125
126
  end
126
127
 
@@ -129,7 +130,7 @@ module Einhorn
129
130
  # handlers. Since it's just an array we push to/shift from, we
130
131
  # can be sure there's no race (such as adding hash keys during
131
132
  # iteration.)
132
- while blk = @@signal_actions.shift
133
+ while (blk = @@signal_actions.shift)
133
134
  blk.call
134
135
  end
135
136
  end
@@ -142,37 +143,45 @@ module Einhorn
142
143
 
143
144
  readable, writeable, _ = IO.select(readable_fds, writeable_fds, nil, time)
144
145
  (readable || []).each do |io|
145
- @@readable[io].each {|reader| reader.notify_readable}
146
+ @@readable[io].each { |reader| reader.notify_readable }
146
147
  end
147
148
 
148
149
  (writeable || []).each do |io|
149
- @@writeable[io].each {|writer| writer.notify_writeable}
150
+ @@writeable[io].each { |writer| writer.notify_writeable }
150
151
  end
151
152
  end
152
153
 
153
154
  def self.run_timers
154
- @@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|
155
156
  # Going to be modifying the set, so let's dup it.
156
- timers.dup.each {|timer| timer.ring!}
157
+ timers.dup.each { |timer| timer.ring! }
157
158
  end
158
159
  end
159
160
 
160
161
  def self.break_loop
161
162
  Einhorn.log_debug("Breaking the loop")
162
163
  begin
163
- @@loopbreak_writer.write_nonblock('a')
164
+ @@loopbreak_writer.write_nonblock("a")
164
165
  rescue Errno::EWOULDBLOCK, Errno::EAGAIN
165
166
  Einhorn.log_error("Loop break pipe is full -- probably means that we are quite backlogged")
166
167
  end
167
168
  end
169
+
170
+ def self.default_timeout=(val)
171
+ @@default_timeout = val.to_i == 0 ? nil : val.to_i
172
+ end
173
+
174
+ def self.default_timeout
175
+ @@default_timeout
176
+ end
168
177
  end
169
178
  end
170
179
 
171
- require 'einhorn/event/persistent'
172
- require 'einhorn/event/timer'
180
+ require "einhorn/event/persistent"
181
+ require "einhorn/event/timer"
173
182
 
174
- require 'einhorn/event/abstract_text_descriptor'
175
- require 'einhorn/event/ack_timer'
176
- require 'einhorn/event/command_server'
177
- require 'einhorn/event/connection'
178
- require 'einhorn/event/loop_breaker'
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"
@@ -0,0 +1,26 @@
1
+ module Einhorn
2
+ class PrctlAbstract
3
+ def self.get_pdeathsig
4
+ raise NotImplementedError
5
+ end
6
+
7
+ def self.set_pdeathsig(signal)
8
+ raise NotImplementedError
9
+ end
10
+ end
11
+
12
+ class PrctlUnimplemented < PrctlAbstract
13
+ # Deliberately empty; NotImplementedError is intended
14
+ end
15
+
16
+ if RUBY_PLATFORM.match?(/linux/)
17
+ begin
18
+ require "einhorn/prctl_linux"
19
+ Prctl = PrctlLinux
20
+ rescue LoadError
21
+ Prctl = PrctlUnimplemented
22
+ end
23
+ else
24
+ Prctl = PrctlUnimplemented
25
+ end
26
+ end
@@ -0,0 +1,48 @@
1
+ require "fiddle"
2
+ require "fiddle/import"
3
+
4
+ module Einhorn
5
+ module PrctlRaw
6
+ extend Fiddle::Importer
7
+ dlload Fiddle.dlopen(nil) # libc
8
+ extern "int prctl(int, unsigned long, unsigned long, unsigned long, unsigned long)"
9
+
10
+ # From linux/prctl.h
11
+ SET_PDEATHSIG = 1
12
+ GET_PDEATHSIG = 2
13
+ end
14
+
15
+ class PrctlLinux < PrctlAbstract
16
+ # Reading integers is hard with fiddle. :(
17
+ IntStruct = Fiddle::CStructBuilder.create(Fiddle::CStruct, [Fiddle::TYPE_INT], ["i"])
18
+
19
+ def self.get_pdeathsig
20
+ out = IntStruct.malloc
21
+ out.i = 0
22
+ if PrctlRaw.prctl(PrctlRaw::GET_PDEATHSIG, out.to_i, 0, 0, 0) != 0
23
+ raise SystemCallError.new("get_pdeathsig", Fiddle.last_error)
24
+ end
25
+
26
+ signo = out.i
27
+ if signo == 0
28
+ return nil
29
+ end
30
+
31
+ Signal.signame(signo)
32
+ end
33
+
34
+ def self.set_pdeathsig(signal)
35
+ signo = if signal.nil?
36
+ 0
37
+ elsif signal.instance_of?(String)
38
+ Signal.list.fetch(signal)
39
+ else
40
+ signal
41
+ end
42
+
43
+ if PrctlRaw.prctl(PrctlRaw::SET_PDEATHSIG, signo, 0, 0, 0) != 0
44
+ raise SystemCallError.new("set_pdeathsig(#{signal})", Fiddle.last_error)
45
+ end
46
+ end
47
+ end
48
+ 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
@@ -1,3 +1,3 @@
1
1
  module Einhorn
2
- VERSION = '0.7.4'
2
+ VERSION = "1.0.0"
3
3
  end
@@ -1,23 +1,21 @@
1
- require 'einhorn/client'
2
- require 'einhorn/command/interface'
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
- begin
10
- ensure_worker!
11
- rescue WorkerError
12
- false
13
- else
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['EINHORN_MASTER_PID']
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
- begin
31
- ack!(*args)
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['EINHORN_CHILD_INDEX']
41
+ index = ENV["EINHORN_CHILD_INDEX"]
46
42
  if index.nil? || index !~ /\A \d+ \z/x
47
43
  index
48
44
  else
@@ -65,45 +61,40 @@ 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=:env, arg=nil)
69
- ensure_worker!
70
- close_after_use = true
71
-
72
- case discovery
73
- when :env
74
- socket = ENV['EINHORN_SOCK_PATH']
75
- client = Einhorn::Client.for_path(socket)
76
- when :fd
77
- raise "No EINHORN_SOCK_FD provided in environment. Did you run einhorn with the -g flag?" unless fd_str = ENV['EINHORN_SOCK_FD']
78
-
79
- fd = Integer(fd_str)
80
- client = Einhorn::Client.for_fd(fd)
81
- close_after_use = false if arg
82
- when :direct
83
- socket = arg
84
- client = Einhorn::Client.for_path(socket)
85
- else
86
- raise "Unrecognized socket discovery mechanism: #{discovery.inspect}. Must be one of :filesystem, :argv, or :direct"
64
+ def self.ack!(discovery = :env, arg = nil)
65
+ handle_command_socket(discovery, arg) do |client|
66
+ client.send_command("command" => "worker:ack", "pid" => $$)
87
67
  end
68
+ end
88
69
 
89
- client.send_command({
90
- 'command' => 'worker:ack',
91
- 'pid' => $$
92
- })
93
-
94
- client.close if close_after_use
95
- true
70
+ # Call this to indicate your child process is up and in a healthy state.
71
+ # Arguments:
72
+ #
73
+ # @request_id: Identifies the request ID of the worker, can be used to debug wedged workers.
74
+ #
75
+ # @discovery: How to discover the master process's command socket.
76
+ # :env: Discover the path from ENV['EINHORN_SOCK_PATH']
77
+ # :fd: Just use the file descriptor in ENV['EINHORN_SOCK_FD'].
78
+ # Must run the master with the -g flag. This is mostly
79
+ # useful if you don't have a nice library like Einhorn::Worker.
80
+ # Then @arg being true causes the FD to be left open after ACK;
81
+ # otherwise it is closed.
82
+ # :direct: Provide the path to the command socket in @arg.
83
+ def self.ping!(request_id, discovery = :env, arg = nil)
84
+ handle_command_socket(discovery, arg) do |client|
85
+ client.send_command("command" => "worker:ping", "pid" => $$, "request_id" => request_id)
86
+ end
96
87
  end
97
88
 
98
- def self.socket(number=nil)
89
+ def self.socket(number = nil)
99
90
  number ||= 0
100
91
  einhorn_fd(number)
101
92
  end
102
93
 
103
- def self.socket!(number=nil)
94
+ def self.socket!(number = nil)
104
95
  number ||= 0
105
96
 
106
- unless count = einhorn_fd_count
97
+ unless (count = einhorn_fd_count)
107
98
  raise "No EINHORN_FD_COUNT provided in environment. Are you running under Einhorn?"
108
99
  end
109
100
 
@@ -111,7 +102,7 @@ module Einhorn
111
102
  raise "Only #{count} FDs available, but FD #{number} was requested"
112
103
  end
113
104
 
114
- unless fd = einhorn_fd(number)
105
+ unless (fd = einhorn_fd(number))
115
106
  raise "No EINHORN_FD_#{number} provided in environment. That's pretty weird"
116
107
  end
117
108
 
@@ -119,14 +110,14 @@ module Einhorn
119
110
  end
120
111
 
121
112
  def self.einhorn_fd(n)
122
- unless raw_fd = ENV["EINHORN_FD_#{n}"]
113
+ unless (raw_fd = ENV["EINHORN_FD_#{n}"])
123
114
  return nil
124
115
  end
125
116
  Integer(raw_fd)
126
117
  end
127
118
 
128
119
  def self.einhorn_fd_count
129
- unless raw_count = ENV['EINHORN_FD_COUNT']
120
+ unless (raw_count = ENV["EINHORN_FD_COUNT"])
130
121
  return 0
131
122
  end
132
123
  Integer(raw_count)
@@ -134,15 +125,42 @@ module Einhorn
134
125
 
135
126
  # Call this to handle graceful shutdown requests to your app.
136
127
  def self.graceful_shutdown(&blk)
137
- Signal.trap('USR2', &blk)
128
+ Signal.trap("USR2", &blk)
138
129
  end
139
130
 
140
- private
131
+ def self.handle_command_socket(discovery, contextual_arg)
132
+ ensure_worker!
133
+ close_after_use = true
134
+
135
+ case discovery
136
+ when :env
137
+ socket = ENV["EINHORN_SOCK_PATH"]
138
+ client = Einhorn::Client.for_path(socket)
139
+ when :fd
140
+ raise "No EINHORN_SOCK_FD provided in environment. Did you run einhorn with the -g flag?" unless (fd_str = ENV["EINHORN_SOCK_FD"])
141
+
142
+ fd = Integer(fd_str)
143
+ client = Einhorn::Client.for_fd(fd)
144
+ close_after_use = false if contextual_arg
145
+ when :direct
146
+ socket = contextual_arg
147
+ client = Einhorn::Client.for_path(socket)
148
+ else
149
+ raise "Unrecognized socket discovery mechanism: #{discovery.inspect}. Must be one of :filesystem, :argv, or :direct"
150
+ end
151
+
152
+ yield client
153
+ client.close if close_after_use
154
+
155
+ true
156
+ end
157
+ private_class_method :handle_command_socket
141
158
 
142
159
  def self.socket_from_filesystem(cmd_name)
143
160
  ppid = Process.ppid
144
161
  socket_path_file = Einhorn::Command::Interface.socket_path_file(ppid)
145
162
  File.read(socket_path_file)
146
163
  end
164
+ private_class_method :socket_from_filesystem
147
165
  end
148
166
  end
@@ -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