einhorn 0.8.2 → 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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +10 -0
  3. data/{LICENSE → LICENSE.txt} +0 -0
  4. data/README.md +5 -36
  5. data/einhorn.gemspec +23 -21
  6. data/example/pool_worker.rb +2 -2
  7. data/example/thin_example +8 -8
  8. data/example/time_server +5 -5
  9. data/lib/einhorn/client.rb +8 -8
  10. data/lib/einhorn/command/interface.rb +92 -98
  11. data/lib/einhorn/command.rb +76 -85
  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 +19 -19
  21. data/lib/einhorn/prctl.rb +2 -2
  22. data/lib/einhorn/prctl_linux.rb +13 -14
  23. data/lib/einhorn/safe_yaml.rb +17 -0
  24. data/lib/einhorn/version.rb +1 -1
  25. data/lib/einhorn/worker.rb +26 -30
  26. data/lib/einhorn/worker_pool.rb +9 -9
  27. data/lib/einhorn.rb +120 -125
  28. metadata +33 -117
  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 -94
  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 -23
  39. data/test/integration/_lib/fixtures/exit_during_upgrade/upgrade_reexec.rb +0 -6
  40. data/test/integration/_lib/fixtures/pdeathsig_printer/pdeathsig_printer.rb +0 -29
  41. data/test/integration/_lib/fixtures/signal_timeout/sleepy_server.rb +0 -23
  42. data/test/integration/_lib/fixtures/upgrade_project/upgrading_server.rb +0 -24
  43. data/test/integration/_lib/helpers/einhorn_helpers.rb +0 -148
  44. data/test/integration/_lib/helpers.rb +0 -4
  45. data/test/integration/_lib.rb +0 -6
  46. data/test/integration/pdeathsig.rb +0 -26
  47. data/test/integration/startup.rb +0 -31
  48. data/test/integration/upgrading.rb +0 -204
  49. data/test/unit/_lib/bad_worker.rb +0 -7
  50. data/test/unit/_lib/sleep_worker.rb +0 -5
  51. data/test/unit/einhorn/client.rb +0 -88
  52. data/test/unit/einhorn/command/interface.rb +0 -49
  53. data/test/unit/einhorn/command.rb +0 -135
  54. data/test/unit/einhorn/event.rb +0 -89
  55. data/test/unit/einhorn/worker_pool.rb +0 -39
  56. data/test/unit/einhorn.rb +0 -96
@@ -1,27 +1,25 @@
1
- require 'pp'
2
- require 'set'
3
- require 'tmpdir'
1
+ require "pp"
2
+ require "set"
3
+ require "tmpdir"
4
4
 
5
- require 'einhorn/command/interface'
6
- require 'einhorn/prctl'
5
+ require "einhorn/command/interface"
6
+ require "einhorn/prctl"
7
7
 
8
8
  module Einhorn
9
9
  module Command
10
10
  def self.reap
11
- begin
12
- while true
13
- Einhorn.log_debug('Going to reap a child process')
14
- pid = Process.wait(-1, Process::WNOHANG)
15
- return unless pid
16
- cleanup(pid)
17
- Einhorn::Event.break_loop
18
- end
19
- rescue Errno::ECHILD
11
+ loop do
12
+ Einhorn.log_debug("Going to reap a child process")
13
+ pid = Process.wait(-1, Process::WNOHANG)
14
+ return unless pid
15
+ cleanup(pid)
16
+ Einhorn::Event.break_loop
20
17
  end
18
+ rescue Errno::ECHILD
21
19
  end
22
20
 
23
21
  def self.cleanup(pid)
24
- unless spec = Einhorn::State.children[pid]
22
+ unless (spec = Einhorn::State.children[pid])
25
23
  Einhorn.log_error("Could not find any config for exited child #{pid.inspect}! This probably indicates a bug in Einhorn.")
26
24
  return
27
25
  end
@@ -31,7 +29,7 @@ module Einhorn
31
29
  # Unacked worker
32
30
  if spec[:type] == :worker && !spec[:acked]
33
31
  Einhorn::State.consecutive_deaths_before_ack += 1
34
- extra = ' before it was ACKed'
32
+ extra = " before it was ACKed"
35
33
  else
36
34
  extra = nil
37
35
  end
@@ -47,7 +45,7 @@ module Einhorn
47
45
  end
48
46
 
49
47
  def self.register_ping(pid, request_id)
50
- unless spec = Einhorn::State.children[pid]
48
+ unless (spec = Einhorn::State.children[pid])
51
49
  Einhorn.log_error("Could not find state for PID #{pid.inspect}; ignoring ACK.")
52
50
  return
53
51
  end
@@ -84,7 +82,7 @@ module Einhorn
84
82
  end
85
83
 
86
84
  def self.register_ack(pid)
87
- unless spec = Einhorn::State.children[pid]
85
+ unless (spec = Einhorn::State.children[pid])
88
86
  Einhorn.log_error("Could not find state for PID #{pid.inspect}; ignoring ACK.")
89
87
  return
90
88
  end
@@ -94,10 +92,8 @@ module Einhorn
94
92
  return
95
93
  end
96
94
 
97
- if Einhorn::State.consecutive_deaths_before_ack > 0
98
- extra = ", breaking the streak of #{Einhorn::State.consecutive_deaths_before_ack} consecutive unacked workers dying"
99
- else
100
- extra = nil
95
+ extra = if Einhorn::State.consecutive_deaths_before_ack > 0
96
+ ", breaking the streak of #{Einhorn::State.consecutive_deaths_before_ack} consecutive unacked workers dying"
101
97
  end
102
98
  Einhorn::State.consecutive_deaths_before_ack = 0
103
99
 
@@ -107,14 +103,14 @@ module Einhorn
107
103
  Einhorn::Event.break_loop
108
104
  end
109
105
 
110
- def self.signal_all(signal, children=nil, record=true)
106
+ def self.signal_all(signal, children = nil, record = true)
111
107
  children ||= Einhorn::WorkerPool.workers
112
108
  signaled = {}
113
109
 
114
110
  Einhorn.log_info("Sending #{signal} to #{children.inspect}", :upgrade)
115
111
 
116
112
  children.each do |child|
117
- unless spec = Einhorn::State.children[child]
113
+ unless (spec = Einhorn::State.children[child])
118
114
  Einhorn.log_error("Trying to send #{signal} to dead child #{child.inspect}. The fact we tried this probably indicates a bug in Einhorn.", :upgrade)
119
115
  next
120
116
  end
@@ -150,10 +146,10 @@ module Einhorn
150
146
 
151
147
  Einhorn.log_info("Child #{child.inspect} is still active after #{Einhorn::State.signal_timeout}s. Sending SIGKILL.")
152
148
  begin
153
- Process.kill('KILL', child)
149
+ Process.kill("KILL", child)
154
150
  rescue Errno::ESRCH
155
151
  end
156
- spec[:signaled].add('KILL')
152
+ spec[:signaled].add("KILL")
157
153
  end
158
154
  end
159
155
 
@@ -161,20 +157,19 @@ module Einhorn
161
157
  end
162
158
  end
163
159
 
164
-
165
160
  def self.increment
166
161
  Einhorn::Event.break_loop
167
162
  old = Einhorn::State.config[:number]
168
163
  new = (Einhorn::State.config[:number] += 1)
169
164
  output = "Incrementing number of workers from #{old} -> #{new}"
170
- $stderr.puts(output)
165
+ warn(output)
171
166
  output
172
167
  end
173
168
 
174
169
  def self.decrement
175
170
  if Einhorn::State.config[:number] <= 1
176
171
  output = "Can't decrease number of workers (already at #{Einhorn::State.config[:number]}). Run kill #{$$} if you really want to kill einhorn."
177
- $stderr.puts(output)
172
+ warn(output)
178
173
  return output
179
174
  end
180
175
 
@@ -182,7 +177,7 @@ module Einhorn
182
177
  old = Einhorn::State.config[:number]
183
178
  new = (Einhorn::State.config[:number] -= 1)
184
179
  output = "Decrementing number of workers from #{old} -> #{new}"
185
- $stderr.puts(output)
180
+ warn(output)
186
181
  output
187
182
  end
188
183
 
@@ -195,12 +190,12 @@ module Einhorn
195
190
  old = Einhorn::State.config[:number]
196
191
  Einhorn::State.config[:number] = new
197
192
  output = "Altering worker count, #{old} -> #{new}. Will "
198
- if old < new
199
- output << "spin up additional workers."
193
+ output << if old < new
194
+ "spin up additional workers."
200
195
  else
201
- output << "gracefully terminate workers."
196
+ "gracefully terminate workers."
202
197
  end
203
- $stderr.puts(output)
198
+ warn(output)
204
199
  output
205
200
  end
206
201
 
@@ -211,8 +206,8 @@ module Einhorn
211
206
  end
212
207
 
213
208
  {
214
- :state => global_state,
215
- :persistent_descriptors => descriptor_state,
209
+ state: global_state,
210
+ persistent_descriptors: descriptor_state
216
211
  }
217
212
  end
218
213
 
@@ -257,8 +252,8 @@ module Einhorn
257
252
 
258
253
  begin
259
254
  Einhorn.initialize_reload_environment
260
- respawn_commandline = Einhorn.upgrade_commandline(['--with-state-fd', read.fileno.to_s])
261
- respawn_commandline << { :close_others => false }
255
+ respawn_commandline = Einhorn.upgrade_commandline(["--with-state-fd", read.fileno.to_s])
256
+ respawn_commandline << {close_others: false}
262
257
  Einhorn.log_info("About to re-exec einhorn master as #{respawn_commandline.inspect}", :reload)
263
258
  Einhorn::Compat.exec(*respawn_commandline)
264
259
  rescue SystemCallError => e
@@ -275,16 +270,16 @@ module Einhorn
275
270
  end
276
271
  end
277
272
 
278
- def self.spinup(cmd=nil)
273
+ def self.spinup(cmd = nil)
279
274
  cmd ||= Einhorn::State.cmd
280
275
  index = next_index
281
276
  expected_ppid = Process.pid
282
- if Einhorn::State.preloaded
283
- pid = fork do
277
+ pid = if Einhorn::State.preloaded
278
+ fork do
284
279
  Einhorn::TransientState.whatami = :worker
285
280
  prepare_child_process
286
281
 
287
- Einhorn.log_info('About to tear down Einhorn state and run einhorn_main')
282
+ Einhorn.log_info("About to tear down Einhorn state and run einhorn_main")
288
283
  Einhorn::Command::Interface.uninit
289
284
  Einhorn::Event.close_all_for_worker
290
285
  Einhorn.set_argv(cmd, true)
@@ -297,7 +292,7 @@ module Einhorn
297
292
  einhorn_main
298
293
  end
299
294
  else
300
- pid = fork do
295
+ fork do
301
296
  Einhorn::TransientState.whatami = :worker
302
297
  prepare_child_process
303
298
 
@@ -314,20 +309,20 @@ module Einhorn
314
309
  setup_parent_watch(expected_ppid)
315
310
 
316
311
  prepare_child_environment(index)
317
- Einhorn::Compat.exec(cmd[0], cmd[1..-1], :close_others => false)
312
+ Einhorn::Compat.exec(cmd[0], cmd[1..-1], close_others: false)
318
313
  end
319
314
  end
320
315
 
321
316
  Einhorn.log_info("===> Launched #{pid} (index: #{index})", :upgrade)
322
317
  Einhorn::State.last_spinup = Time.now
323
318
  Einhorn::State.children[pid] = {
324
- :type => :worker,
325
- :version => Einhorn::State.version,
326
- :acked => false,
327
- :signaled => Set.new,
328
- :last_signaled_at => nil,
329
- :index => index,
330
- :spinup_time => Einhorn::State.last_spinup,
319
+ type: :worker,
320
+ version: Einhorn::State.version,
321
+ acked: false,
322
+ signaled: Set.new,
323
+ last_signaled_at: nil,
324
+ index: index,
325
+ spinup_time: Einhorn::State.last_spinup
331
326
  }
332
327
 
333
328
  # Set up whatever's needed for ACKing
@@ -336,6 +331,7 @@ module Einhorn
336
331
  when :timer
337
332
  Einhorn::Event::ACKTimer.open(ack_mode[:timeout], pid)
338
333
  when :manual
334
+ # nothing to do
339
335
  else
340
336
  Einhorn.log_error("Unrecognized ACK mode #{type.inspect}")
341
337
  end
@@ -343,24 +339,18 @@ module Einhorn
343
339
 
344
340
  def self.prepare_child_environment(index)
345
341
  # This is run from the child
346
- ENV['EINHORN_MASTER_PID'] = Process.ppid.to_s
347
- ENV['EINHORN_SOCK_PATH'] = Einhorn::Command::Interface.socket_path
342
+ ENV["EINHORN_MASTER_PID"] = Process.ppid.to_s
343
+ ENV["EINHORN_SOCK_PATH"] = Einhorn::Command::Interface.socket_path
348
344
  if Einhorn::State.command_socket_as_fd
349
345
  socket = UNIXSocket.open(Einhorn::Command::Interface.socket_path)
350
346
  Einhorn::TransientState.socket_handles << socket
351
- ENV['EINHORN_SOCK_FD'] = socket.fileno.to_s
347
+ ENV["EINHORN_SOCK_FD"] = socket.fileno.to_s
352
348
  end
353
349
 
354
- ENV['EINHORN_FD_COUNT'] = Einhorn::State.bind_fds.length.to_s
355
- Einhorn::State.bind_fds.each_with_index {|fd, i| ENV["EINHORN_FD_#{i}"] = fd.to_s}
356
-
357
- ENV['EINHORN_CHILD_INDEX'] = index.to_s
350
+ ENV["EINHORN_FD_COUNT"] = Einhorn::State.bind_fds.length.to_s
351
+ Einhorn::State.bind_fds.each_with_index { |fd, i| ENV["EINHORN_FD_#{i}"] = fd.to_s }
358
352
 
359
- # EINHORN_FDS is deprecated. It was originally an attempt to
360
- # match Upstart's nominal internal support for space-separated
361
- # FD lists, but nobody uses that in practice, and it makes
362
- # finding individual FDs more difficult
363
- ENV['EINHORN_FDS'] = Einhorn::State.bind_fds.map(&:to_s).join(' ')
353
+ ENV["EINHORN_CHILD_INDEX"] = index.to_s
364
354
  end
365
355
 
366
356
  # Reseed common ruby random number generators.
@@ -383,11 +373,11 @@ module Einhorn
383
373
 
384
374
  # reseed OpenSSL::Random if it's loaded
385
375
  if defined?(OpenSSL::Random)
386
- if defined?(Random)
387
- seed = Random.new_seed
376
+ seed = if defined?(Random)
377
+ Random.new_seed
388
378
  else
389
379
  # Ruby 1.8
390
- seed = rand
380
+ rand
391
381
  end
392
382
  OpenSSL::Random.seed(seed.to_s)
393
383
  end
@@ -399,14 +389,14 @@ module Einhorn
399
389
  end
400
390
 
401
391
  def self.setup_parent_watch(expected_ppid)
402
- if Einhorn::State.kill_children_on_exit then
392
+ if Einhorn::State.kill_children_on_exit
403
393
  begin
404
394
  # NB: Having the USR2 signal handler set to terminate (the default) at
405
395
  # this point is required. If it's set to a ruby handler, there are
406
396
  # race conditions that could cause the worker to leak.
407
397
 
408
398
  Einhorn::Prctl.set_pdeathsig("USR2")
409
- if Process.ppid != expected_ppid then
399
+ if Process.ppid != expected_ppid
410
400
  Einhorn.log_error("Parent process died before we set pdeathsig; cowardly refusing to exec child process.")
411
401
  exit(1)
412
402
  end
@@ -424,18 +414,19 @@ module Einhorn
424
414
  # upgrade, bring up all the new workers and don't cull any old workers
425
415
  # until they're all up.
426
416
  #
427
- def self.full_upgrade(options={})
428
- options = {:smooth => false}.merge(options)
417
+ def self.full_upgrade(options = {})
418
+ options = {smooth: false}.merge(options)
429
419
 
430
420
  Einhorn::State.smooth_upgrade = options.fetch(:smooth)
431
421
  reload_for_upgrade
432
422
  end
433
423
 
434
424
  def self.full_upgrade_smooth
435
- full_upgrade(:smooth => true)
425
+ full_upgrade(smooth: true)
436
426
  end
427
+
437
428
  def self.full_upgrade_fleet
438
- full_upgrade(:smooth => false)
429
+ full_upgrade(smooth: false)
439
430
  end
440
431
 
441
432
  def self.reload_for_upgrade
@@ -448,8 +439,8 @@ module Einhorn
448
439
  Einhorn.log_info("Currently upgrading (#{Einhorn::WorkerPool.ack_count} / #{Einhorn::WorkerPool.ack_target} ACKs; bumping version and starting over)...", :upgrade)
449
440
  else
450
441
  Einhorn::State.upgrading = true
451
- u_type = Einhorn::State.smooth_upgrade ? 'smooth' : 'fleet'
452
- Einhorn.log_info("Starting #{u_type} upgrade from version" +
442
+ u_type = Einhorn::State.smooth_upgrade ? "smooth" : "fleet"
443
+ Einhorn.log_info("Starting #{u_type} upgrade from version" \
453
444
  " #{Einhorn::State.version}...", :upgrade)
454
445
  end
455
446
 
@@ -496,7 +487,7 @@ module Einhorn
496
487
  end
497
488
 
498
489
  if unsignaled > target
499
- excess = Einhorn::WorkerPool.unsignaled_modern_workers_with_priority[0...(unsignaled-target)]
490
+ excess = Einhorn::WorkerPool.unsignaled_modern_workers_with_priority[0...(unsignaled - target)]
500
491
  Einhorn.log_info("Have too many workers at the current version, so killing off #{excess.length} of them.")
501
492
  signal_all("USR2", excess)
502
493
  end
@@ -507,13 +498,13 @@ module Einhorn
507
498
 
508
499
  def self.kill_expired_signaled_workers
509
500
  now = Time.now
510
- children = Einhorn::State.children.select do |_,c|
501
+ children = Einhorn::State.children.select do |_, c|
511
502
  # Only interested in USR2 signaled workers
512
503
  next unless c[:signaled] && c[:signaled].length > 0
513
- next unless c[:signaled].include?('USR2')
504
+ next unless c[:signaled].include?("USR2")
514
505
 
515
506
  # Ignore processes that have received KILL since it can't be trapped.
516
- next if c[:signaled].include?('KILL')
507
+ next if c[:signaled].include?("KILL")
517
508
 
518
509
  # Filter out those children that have not reached signal_timeout yet.
519
510
  next unless c[:last_signaled_at]
@@ -527,12 +518,12 @@ module Einhorn
527
518
  children.each do |pid, child|
528
519
  Einhorn.log_info("Child #{pid.inspect} was signaled #{(child[:last_signaled_at] - now).abs.to_i}s ago. Sending SIGKILL as it is still active after #{Einhorn::State.signal_timeout}s timeout.", :upgrade)
529
520
  begin
530
- Process.kill('KILL', pid)
521
+ Process.kill("KILL", pid)
531
522
  rescue Errno::ESRCH
532
523
  Einhorn.log_debug("Attempted to SIGKILL child #{pid.inspect} but the process does not exist.")
533
524
  end
534
525
 
535
- child[:signaled].add('KILL')
526
+ child[:signaled].add("KILL")
536
527
  child[:last_signaled_at] = Time.now
537
528
  end
538
529
  end
@@ -559,7 +550,7 @@ module Einhorn
559
550
  return
560
551
  end
561
552
  Einhorn.log_info("Launching #{missing} new workers")
562
- missing.times {spinup}
553
+ missing.times { spinup }
563
554
  end
564
555
 
565
556
  # Unbounded exponential backoff is not a thing: we run into problems if
@@ -568,7 +559,7 @@ module Einhorn
568
559
  # don't wait until the heat death of the universe to spin up new capacity.
569
560
  MAX_SPINUP_INTERVAL = 30.0
570
561
 
571
- def self.replenish_gradually(max_unacked=nil)
562
+ def self.replenish_gradually(max_unacked = nil)
572
563
  return if Einhorn::TransientState.has_outstanding_spinup_timer
573
564
  return unless Einhorn::WorkerPool.missing_worker_count > 0
574
565
 
@@ -591,7 +582,7 @@ module Einhorn
591
582
 
592
583
  # Exponentially backoff automated spinup if we're just having
593
584
  # things die before ACKing
594
- spinup_interval = Einhorn::State.config[:seconds] * (1.5 ** Einhorn::State.consecutive_deaths_before_ack)
585
+ spinup_interval = Einhorn::State.config[:seconds] * (1.5**Einhorn::State.consecutive_deaths_before_ack)
595
586
  spinup_interval = [spinup_interval, MAX_SPINUP_INTERVAL].min
596
587
  seconds_ago = (Time.now - Einhorn::State.last_spinup).to_f
597
588
 
@@ -618,14 +609,14 @@ module Einhorn
618
609
  end
619
610
  end
620
611
 
621
- def self.quieter(log=true)
612
+ def self.quieter(log = true)
622
613
  Einhorn::State.verbosity += 1 if Einhorn::State.verbosity < 2
623
614
  output = "Verbosity set to #{Einhorn::State.verbosity}"
624
615
  Einhorn.log_info(output) if log
625
616
  output
626
617
  end
627
618
 
628
- def self.louder(log=true)
619
+ def self.louder(log = true)
629
620
  Einhorn::State.verbosity -= 1 if Einhorn::State.verbosity > 0
630
621
  output = "Verbosity set to #{Einhorn::State.verbosity}"
631
622
  Einhorn.log_info(output) if log
@@ -11,10 +11,10 @@ module Einhorn
11
11
 
12
12
  def self.cloexec!(fd, enable)
13
13
  original = fd.fcntl(Fcntl::F_GETFD)
14
- if enable
15
- new = original | Fcntl::FD_CLOEXEC
14
+ new = if enable
15
+ original | Fcntl::FD_CLOEXEC
16
16
  else
17
- new = original & (-Fcntl::FD_CLOEXEC-1)
17
+ original & (-Fcntl::FD_CLOEXEC - 1)
18
18
  end
19
19
  fd.fcntl(Fcntl::F_SETFD, new)
20
20
  end
@@ -24,7 +24,7 @@ module Einhorn
24
24
  end
25
25
 
26
26
  # Opts are ignored in Ruby 1.8
27
- def self.exec(script, args, opts={})
27
+ def self.exec(script, args, opts = {})
28
28
  cmd = [script, script]
29
29
  begin
30
30
  Kernel.exec(cmd, *(args + [opts]))
@@ -53,18 +53,18 @@ module Einhorn
53
53
 
54
54
  # linux / friends
55
55
  begin
56
- return File.read('/proc/cpuinfo').scan(/^processor\s*:/).count
56
+ return File.read("/proc/cpuinfo").scan(/^processor\s*:/).count
57
57
  rescue Errno::ENOENT
58
58
  end
59
59
 
60
60
  # OS X
61
- if RUBY_PLATFORM =~ /darwin/
61
+ if RUBY_PLATFORM.match?(/darwin/)
62
62
  return Integer(`sysctl -n hw.logicalcpu`)
63
63
  end
64
64
 
65
65
  # windows / friends
66
66
  begin
67
- require 'win32ole'
67
+ require "win32ole"
68
68
  rescue LoadError
69
69
  else
70
70
  wmi = WIN32OLE.connect("winmgmts://")
@@ -6,7 +6,7 @@ module Einhorn::Event
6
6
  @@instance_counter = 0
7
7
 
8
8
  def self.open(sock)
9
- self.new(sock)
9
+ new(sock)
10
10
  end
11
11
 
12
12
  def initialize(sock)
@@ -40,24 +40,22 @@ module Einhorn::Event
40
40
  end
41
41
 
42
42
  def notify_readable
43
- while true
44
- begin
45
- return if @closed
46
- chunk = @socket.read_nonblock(1024)
47
- rescue Errno::EAGAIN
48
- break
49
- rescue EOFError, Errno::EPIPE, Errno::ECONNRESET
50
- close
51
- break
52
- rescue StandardError => e
53
- log_error("Caught unrecognized error while reading from socket: #{e} (#{e.class})")
54
- close
55
- break
56
- else
57
- log_debug("read #{chunk.length} bytes (#{chunk.inspect[0..20]})")
58
- @read_buffer << chunk
59
- process_read_buffer
60
- end
43
+ loop do
44
+ return if @closed
45
+ chunk = @socket.read_nonblock(1024)
46
+ rescue Errno::EAGAIN
47
+ break
48
+ rescue EOFError, Errno::EPIPE, Errno::ECONNRESET
49
+ close
50
+ break
51
+ rescue => e
52
+ log_error("Caught unrecognized error while reading from socket: #{e} (#{e.class})")
53
+ close
54
+ break
55
+ else
56
+ log_debug("read #{chunk.length} bytes (#{chunk.inspect[0..20]})")
57
+ @read_buffer << chunk
58
+ process_read_buffer
61
59
  end
62
60
  end
63
61
 
@@ -72,19 +70,17 @@ module Einhorn::Event
72
70
  end
73
71
 
74
72
  def notify_writeable
75
- begin
76
- return if @closed
77
- written = @socket.write_nonblock(@write_buffer)
78
- rescue Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EINTR
79
- rescue Errno::EPIPE, Errno::ECONNRESET
80
- close
81
- rescue StandardError => e
82
- log_error("Caught unrecognized error while writing to socket: #{e} (#{e.class})")
83
- close
84
- else
85
- log_debug("wrote #{written} bytes")
86
- @write_buffer = @write_buffer[written..-1]
87
- end
73
+ return if @closed
74
+ written = @socket.write_nonblock(@write_buffer)
75
+ rescue Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EINTR
76
+ rescue Errno::EPIPE, Errno::ECONNRESET
77
+ close
78
+ rescue => e
79
+ log_error("Caught unrecognized error while writing to socket: #{e} (#{e.class})")
80
+ close
81
+ else
82
+ log_debug("wrote #{written} bytes")
83
+ @write_buffer = @write_buffer[written..-1]
88
84
  end
89
85
 
90
86
  def to_io
@@ -102,9 +98,9 @@ module Einhorn::Event
102
98
  end
103
99
 
104
100
  def process_read_buffer
105
- while true
101
+ loop do
106
102
  if @read_buffer.length > 0
107
- break unless split = parse_record
103
+ break unless (split = parse_record)
108
104
  record, remainder = split
109
105
  log_debug("Read a record of #{record.length} bytes.")
110
106
  @read_buffer = remainder
@@ -117,7 +113,7 @@ module Einhorn::Event
117
113
 
118
114
  # Override in subclass. This lets you do streaming reads.
119
115
  def parse_record
120
- [@read_buffer, '']
116
+ [@read_buffer, ""]
121
117
  end
122
118
 
123
119
  def consume_record(record)
@@ -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