resurrected_god 0.14.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +559 -0
  3. data/README.md +9 -4
  4. data/bin/god +26 -28
  5. data/ext/god/extconf.rb +9 -9
  6. data/lib/god/behavior.rb +3 -5
  7. data/lib/god/behaviors/clean_pid_file.rb +4 -6
  8. data/lib/god/behaviors/clean_unix_socket.rb +4 -6
  9. data/lib/god/behaviors/notify_when_flapping.rb +13 -15
  10. data/lib/god/cli/command.rb +109 -89
  11. data/lib/god/cli/run.rb +51 -75
  12. data/lib/god/cli/version.rb +2 -4
  13. data/lib/god/condition.rb +12 -14
  14. data/lib/god/conditions/always.rb +3 -2
  15. data/lib/god/conditions/complex.rb +23 -24
  16. data/lib/god/conditions/cpu_usage.rb +12 -16
  17. data/lib/god/conditions/degrading_lambda.rb +15 -19
  18. data/lib/god/conditions/disk_usage.rb +7 -8
  19. data/lib/god/conditions/file_mtime.rb +3 -7
  20. data/lib/god/conditions/file_touched.rb +4 -5
  21. data/lib/god/conditions/flapping.rb +57 -62
  22. data/lib/god/conditions/http_response_code.rb +27 -32
  23. data/lib/god/conditions/lambda.rb +3 -5
  24. data/lib/god/conditions/memory_usage.rb +12 -16
  25. data/lib/god/conditions/process_exits.rb +12 -12
  26. data/lib/god/conditions/process_running.rb +8 -10
  27. data/lib/god/conditions/socket_responding.rb +23 -28
  28. data/lib/god/conditions/tries.rb +12 -14
  29. data/lib/god/configurable.rb +7 -10
  30. data/lib/god/contact.rb +41 -52
  31. data/lib/god/contacts/airbrake.rb +10 -12
  32. data/lib/god/contacts/campfire.rb +18 -20
  33. data/lib/god/contacts/email.rb +27 -28
  34. data/lib/god/contacts/prowl.rb +16 -17
  35. data/lib/god/contacts/scout.rb +2 -5
  36. data/lib/god/contacts/sensu.rb +15 -11
  37. data/lib/god/contacts/slack.rb +23 -33
  38. data/lib/god/contacts/statsd.rb +8 -8
  39. data/lib/god/contacts/twitter.rb +2 -2
  40. data/lib/god/contacts/webhook.rb +21 -24
  41. data/lib/god/driver.rb +12 -18
  42. data/lib/god/errors.rb +0 -2
  43. data/lib/god/event_handler.rb +40 -49
  44. data/lib/god/event_handlers/dummy_handler.rb +1 -1
  45. data/lib/god/event_handlers/kqueue_handler.rb +2 -2
  46. data/lib/god/event_handlers/netlink_handler.rb +1 -1
  47. data/lib/god/logger.rb +5 -13
  48. data/lib/god/metric.rb +13 -15
  49. data/lib/god/process.rb +93 -98
  50. data/lib/god/simple_logger.rb +13 -15
  51. data/lib/god/socket.rb +21 -23
  52. data/lib/god/sugar.rb +8 -8
  53. data/lib/god/sys_logger.rb +6 -8
  54. data/lib/god/system/portable_poller.rb +1 -9
  55. data/lib/god/system/process.rb +4 -6
  56. data/lib/god/system/slash_proc_poller.rb +17 -19
  57. data/lib/god/task.rb +110 -136
  58. data/lib/god/timeline.rb +2 -4
  59. data/lib/god/trigger.rb +7 -11
  60. data/lib/god/version.rb +1 -1
  61. data/lib/god/watch.rb +51 -57
  62. data/lib/god.rb +122 -148
  63. metadata +17 -370
  64. data/Announce.txt +0 -135
  65. data/Gemfile +0 -5
  66. data/Rakefile +0 -129
  67. data/doc/god.asciidoc +0 -1592
  68. data/doc/intro.asciidoc +0 -20
  69. data/ext/god/.gitignore +0 -5
  70. data/lib/god/compat19.rb +0 -33
  71. data/lib/god/contacts/hipchat.rb +0 -117
  72. data/lib/god/contacts/jabber.rb +0 -75
  73. data/test/configs/child_events/child_events.god +0 -44
  74. data/test/configs/child_events/simple_server.rb +0 -3
  75. data/test/configs/child_polls/child_polls.god +0 -37
  76. data/test/configs/child_polls/simple_server.rb +0 -12
  77. data/test/configs/complex/complex.god +0 -59
  78. data/test/configs/complex/simple_server.rb +0 -3
  79. data/test/configs/contact/contact.god +0 -118
  80. data/test/configs/contact/simple_server.rb +0 -3
  81. data/test/configs/daemon_events/daemon_events.god +0 -37
  82. data/test/configs/daemon_events/simple_server.rb +0 -8
  83. data/test/configs/daemon_events/simple_server_stop.rb +0 -11
  84. data/test/configs/daemon_polls/daemon_polls.god +0 -17
  85. data/test/configs/daemon_polls/simple_server.rb +0 -6
  86. data/test/configs/degrading_lambda/degrading_lambda.god +0 -31
  87. data/test/configs/degrading_lambda/tcp_server.rb +0 -15
  88. data/test/configs/keepalive/keepalive.god +0 -9
  89. data/test/configs/keepalive/keepalive.rb +0 -12
  90. data/test/configs/lifecycle/lifecycle.god +0 -25
  91. data/test/configs/matias/matias.god +0 -50
  92. data/test/configs/real.rb +0 -59
  93. data/test/configs/running_load/running_load.god +0 -16
  94. data/test/configs/stop_options/simple_server.rb +0 -12
  95. data/test/configs/stop_options/stop_options.god +0 -39
  96. data/test/configs/stress/simple_server.rb +0 -3
  97. data/test/configs/stress/stress.god +0 -15
  98. data/test/configs/task/logs/.placeholder +0 -0
  99. data/test/configs/task/task.god +0 -26
  100. data/test/configs/test.rb +0 -61
  101. data/test/configs/usr1_trapper.rb +0 -10
  102. data/test/helper.rb +0 -172
  103. data/test/suite.rb +0 -6
  104. data/test/test_airbrake.rb +0 -14
  105. data/test/test_behavior.rb +0 -18
  106. data/test/test_campfire.rb +0 -22
  107. data/test/test_condition.rb +0 -52
  108. data/test/test_conditions_disk_usage.rb +0 -50
  109. data/test/test_conditions_http_response_code.rb +0 -109
  110. data/test/test_conditions_process_running.rb +0 -40
  111. data/test/test_conditions_socket_responding.rb +0 -176
  112. data/test/test_conditions_tries.rb +0 -67
  113. data/test/test_contact.rb +0 -109
  114. data/test/test_driver.rb +0 -26
  115. data/test/test_email.rb +0 -34
  116. data/test/test_event_handler.rb +0 -82
  117. data/test/test_god.rb +0 -710
  118. data/test/test_god_system.rb +0 -201
  119. data/test/test_handlers_kqueue_handler.rb +0 -16
  120. data/test/test_hipchat.rb +0 -23
  121. data/test/test_jabber.rb +0 -29
  122. data/test/test_logger.rb +0 -55
  123. data/test/test_metric.rb +0 -74
  124. data/test/test_process.rb +0 -263
  125. data/test/test_prowl.rb +0 -15
  126. data/test/test_registry.rb +0 -15
  127. data/test/test_sensu.rb +0 -11
  128. data/test/test_slack.rb +0 -57
  129. data/test/test_socket.rb +0 -34
  130. data/test/test_statsd.rb +0 -22
  131. data/test/test_sugar.rb +0 -42
  132. data/test/test_system_portable_poller.rb +0 -17
  133. data/test/test_system_process.rb +0 -30
  134. data/test/test_task.rb +0 -246
  135. data/test/test_timeline.rb +0 -37
  136. data/test/test_trigger.rb +0 -63
  137. data/test/test_watch.rb +0 -286
  138. data/test/test_webhook.rb +0 -22
data/lib/god.rb CHANGED
@@ -8,15 +8,6 @@ if $load_god
8
8
  require 'stringio'
9
9
  require 'fileutils'
10
10
 
11
- begin
12
- require 'fastthread'
13
- rescue LoadError
14
- ensure
15
- require 'thread'
16
- end
17
-
18
- # stdlib
19
-
20
11
  # internal requires
21
12
  require 'god/errors'
22
13
  require 'god/simple_logger'
@@ -65,14 +56,10 @@ if $load_god
65
56
  require 'god/registry'
66
57
  require 'god/process'
67
58
 
59
+ require 'god/version'
68
60
  require 'god/cli/version'
69
61
  require 'god/cli/command'
70
62
 
71
- # ruby 1.8 specific configuration
72
- if RUBY_VERSION < '1.9'
73
- $KCODE = 'u'
74
- end
75
-
76
63
  CONTACT_DEPS = {}
77
64
  CONTACT_LOAD_SUCCESS = {}
78
65
 
@@ -85,9 +72,7 @@ if $load_god
85
72
 
86
73
  require 'god/contact'
87
74
  load_contact(:campfire)
88
- load_contact(:hipchat)
89
75
  load_contact(:email)
90
- load_contact(:jabber)
91
76
  load_contact(:prowl)
92
77
  load_contact(:scout)
93
78
  load_contact(:statsd)
@@ -97,7 +82,7 @@ if $load_god
97
82
  load_contact(:slack)
98
83
  load_contact(:sensu)
99
84
 
100
- $:.unshift File.join(File.dirname(__FILE__), *%w[.. ext god])
85
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), *%w[.. ext god])
101
86
 
102
87
  # App wide logging system
103
88
  LOG = God::Logger.new
@@ -120,7 +105,7 @@ if $load_god
120
105
  end
121
106
 
122
107
  module Kernel
123
- alias_method :abort_orig, :abort
108
+ alias abort_orig abort
124
109
 
125
110
  def abort(text = nil)
126
111
  $run = false
@@ -128,7 +113,7 @@ if $load_god
128
113
  exit(1)
129
114
  end
130
115
 
131
- alias_method :exit_orig, :exit
116
+ alias exit_orig exit
132
117
 
133
118
  def exit(code = 0)
134
119
  $run = false
@@ -139,43 +124,38 @@ if $load_god
139
124
  class Module
140
125
  def safe_attr_accessor(*args)
141
126
  args.each do |arg|
142
- define_method((arg.to_s + "=").intern) do |other|
143
- if !self.running && self.inited
144
- abort "God.#{arg} must be set before any Tasks are defined"
145
- end
127
+ define_method("#{arg}=".intern) do |other|
128
+ abort "God.#{arg} must be set before any Tasks are defined" if !running && inited
146
129
 
147
- if self.running && self.inited
130
+ if running && inited
148
131
  applog(nil, :warn, "God.#{arg} can't be set while god is running")
149
132
  return
150
133
  end
151
134
 
152
- instance_variable_set(('@' + arg.to_s).intern, other)
135
+ instance_variable_set("@#{arg}".intern, other)
153
136
  end
154
137
 
155
138
  define_method(arg) do
156
- instance_variable_get(('@' + arg.to_s).intern)
139
+ instance_variable_get("@#{arg}".intern)
157
140
  end
158
141
  end
159
142
  end
160
143
  end
161
144
 
162
- module God
163
- # The String version number for this package.
164
- VERSION = '0.14.0'
165
-
145
+ module God
166
146
  # The Integer number of lines of backlog to keep for the logger.
167
147
  LOG_BUFFER_SIZE_DEFAULT = 100
168
148
 
169
149
  # An Array of directory paths to be used as the default PID file directory.
170
150
  # This list will be searched in order and the first one that has write
171
151
  # permissions will be used.
172
- PID_FILE_DIRECTORY_DEFAULTS = ['/var/run/god', '~/.god/pids']
152
+ PID_FILE_DIRECTORY_DEFAULTS = ['/var/run/god', '~/.god/pids'].freeze
173
153
 
174
- # The default Integer port number for the DRb communcations channel.
154
+ # The default Integer port number for the DRb communications channel.
175
155
  DRB_PORT_DEFAULT = 17165
176
156
 
177
157
  # The default Array of String IPs that will allow DRb communication access.
178
- DRB_ALLOW_DEFAULT = ['127.0.0.1']
158
+ DRB_ALLOW_DEFAULT = ['127.0.0.1'].freeze
179
159
 
180
160
  # The default Symbol log level.
181
161
  LOG_LEVEL_DEFAULT = :info
@@ -188,7 +168,7 @@ module God
188
168
  STOP_TIMEOUT_DEFAULT = 10
189
169
 
190
170
  # The default String signal to send for the stop command.
191
- STOP_SIGNAL_DEFAULT = 'TERM'
171
+ STOP_SIGNAL_DEFAULT = 'TERM'.freeze
192
172
 
193
173
  class << self
194
174
  # user configurable
@@ -237,7 +217,7 @@ module God
237
217
  # Returns nothing.
238
218
  def self.internal_init
239
219
  # Only do this once.
240
- return if self.inited
220
+ return if inited
241
221
 
242
222
  # Variable init.
243
223
  self.watches = {}
@@ -255,14 +235,14 @@ module God
255
235
  self.terminate_timeout ||= TERMINATE_TIMEOUT_DEFAULT
256
236
 
257
237
  # Additional setup.
258
- self.setup
238
+ setup
259
239
 
260
240
  # Log level.
261
- log_level_map = { :debug => Logger::DEBUG,
262
- :info => Logger::INFO,
263
- :warn => Logger::WARN,
264
- :error => Logger::ERROR,
265
- :fatal => Logger::FATAL }
241
+ log_level_map = { debug: Logger::DEBUG,
242
+ info: Logger::INFO,
243
+ warn: Logger::WARN,
244
+ error: Logger::ERROR,
245
+ fatal: Logger::FATAL }
266
246
  LOG.level = log_level_map[self.log_level]
267
247
 
268
248
  # Init has been executed.
@@ -278,7 +258,7 @@ module God
278
258
  #
279
259
  # Returns nothing.
280
260
  def self.watch(&block)
281
- self.task(Watch, &block)
261
+ task(Watch, &block)
282
262
  end
283
263
 
284
264
  # Instantiate a new, empty Task object and yield it to the mandatory block.
@@ -288,7 +268,7 @@ module God
288
268
  # Returns nothing.
289
269
  def self.task(klass = Task)
290
270
  # Ensure internal init has run.
291
- self.internal_init
271
+ internal_init
292
272
 
293
273
  t = klass.new
294
274
  yield(t)
@@ -298,44 +278,40 @@ module God
298
278
 
299
279
  # If running, completely remove the watch (if necessary) to prepare for
300
280
  # the reload
301
- existing_watch = self.watches[t.name]
302
- if self.running && existing_watch
303
- self.pending_watch_states[existing_watch.name] = existing_watch.state
304
- self.unwatch(existing_watch)
281
+ existing_watch = watches[t.name]
282
+ if running && existing_watch
283
+ pending_watch_states[existing_watch.name] = existing_watch.state
284
+ unwatch(existing_watch)
305
285
  end
306
286
 
307
287
  # Ensure the new watch has a unique name.
308
- if self.watches[t.name] || self.groups[t.name]
309
- abort "Task name '#{t.name}' already used for a Task or Group"
310
- end
288
+ abort "Task name '#{t.name}' already used for a Task or Group" if watches[t.name] || groups[t.name]
311
289
 
312
290
  # Ensure watch is internally valid.
313
291
  t.valid? || abort("Task '#{t.name}' is not valid (see above)")
314
292
 
315
293
  # Add to list of watches.
316
- self.watches[t.name] = t
294
+ watches[t.name] = t
317
295
 
318
296
  # Add to pending watches.
319
- self.pending_watches << t
297
+ pending_watches << t
320
298
 
321
299
  # Add to group if specified.
322
300
  if t.group
323
301
  # Ensure group name hasn't been used for a watch already.
324
- if self.watches[t.group]
325
- abort "Group name '#{t.group}' already used for a Task"
326
- end
302
+ abort "Group name '#{t.group}' already used for a Task" if watches[t.group]
327
303
 
328
- self.groups[t.group] ||= []
329
- self.groups[t.group] << t
304
+ groups[t.group] ||= []
305
+ groups[t.group] << t
330
306
  end
331
307
 
332
308
  # Register watch.
333
309
  t.register!
334
310
 
335
311
  # Log.
336
- if self.running && existing_watch
312
+ if running && existing_watch
337
313
  applog(t, :info, "#{t.name} Reloaded config")
338
- elsif self.running
314
+ elsif running
339
315
  applog(t, :info, "#{t.name} Loaded config")
340
316
  end
341
317
  end
@@ -353,12 +329,10 @@ module God
353
329
  watch.unregister!
354
330
 
355
331
  # Remove from watches.
356
- self.watches.delete(watch.name)
332
+ watches.delete(watch.name)
357
333
 
358
334
  # Remove from groups.
359
- if watch.group
360
- self.groups[watch.group].delete(watch)
361
- end
335
+ groups[watch.group].delete(watch) if watch.group
362
336
 
363
337
  applog(watch, :info, "#{watch.name} unwatched")
364
338
  end
@@ -372,12 +346,12 @@ module God
372
346
  # Returns nothing.
373
347
  def self.contact(kind)
374
348
  # Ensure internal init has run.
375
- self.internal_init
349
+ internal_init
376
350
 
377
351
  # Verify contact has been loaded.
378
352
  if CONTACT_LOAD_SUCCESS[kind] == false
379
353
  applog(nil, :error, "A required dependency for the #{kind} contact is unavailable.")
380
- applog(nil, :error, "Run the following commands to install the dependencies:")
354
+ applog(nil, :error, 'Run the following commands to install the dependencies:')
381
355
  CONTACT_DEPS[kind].each do |d|
382
356
  applog(nil, :error, " [sudo] gem install #{d}")
383
357
  end
@@ -398,36 +372,30 @@ module God
398
372
  c.prepare
399
373
 
400
374
  # Remove existing contacts of same name.
401
- existing_contact = self.contacts[c.name]
402
- if self.running && existing_contact
403
- self.uncontact(existing_contact)
404
- end
375
+ existing_contact = contacts[c.name]
376
+ uncontact(existing_contact) if running && existing_contact
405
377
 
406
378
  # Warn and noop if the contact has been defined before.
407
- if self.contacts[c.name] || self.contact_groups[c.name]
379
+ if contacts[c.name] || contact_groups[c.name]
408
380
  applog(nil, :warn, "Contact name '#{c.name}' already used for a Contact or Contact Group")
409
381
  return
410
382
  end
411
383
 
412
384
  # Abort if the Contact is invalid, the Contact will have printed out its
413
385
  # own error messages by now.
414
- unless Contact.valid?(c) && c.valid?
415
- abort "Exiting on invalid contact"
416
- end
386
+ abort 'Exiting on invalid contact' unless Contact.valid?(c) && c.valid?
417
387
 
418
388
  # Add to list of contacts.
419
- self.contacts[c.name] = c
389
+ contacts[c.name] = c
420
390
 
421
391
  # Add to contact group if specified.
422
- if c.group
423
- # Ensure group name hasn't been used for a contact already.
424
- if self.contacts[c.group]
425
- abort "Contact Group name '#{c.group}' already used for a Contact"
426
- end
392
+ return unless c.group
427
393
 
428
- self.contact_groups[c.group] ||= []
429
- self.contact_groups[c.group] << c
430
- end
394
+ # Ensure group name hasn't been used for a contact already.
395
+ abort "Contact Group name '#{c.group}' already used for a Contact" if contacts[c.group]
396
+
397
+ contact_groups[c.group] ||= []
398
+ contact_groups[c.group] << c
431
399
  end
432
400
 
433
401
  # Remove the given contact from god.
@@ -436,16 +404,16 @@ module God
436
404
  #
437
405
  # Returns nothing.
438
406
  def self.uncontact(contact)
439
- self.contacts.delete(contact.name)
440
- if contact.group
441
- self.contact_groups[contact.group].delete(contact)
442
- end
407
+ contacts.delete(contact.name)
408
+ return unless contact.group
409
+
410
+ contact_groups[contact.group].delete(contact)
443
411
  end
444
412
 
445
413
  def self.watches_by_name(name)
446
414
  case name
447
- when "", nil then self.watches.values.dup
448
- else Array(self.watches[name] || self.groups[name]).dup
415
+ when '', nil then watches.values.dup
416
+ else Array(watches[name] || groups[name]).dup
449
417
  end
450
418
  end
451
419
 
@@ -458,29 +426,34 @@ module God
458
426
  # Returns an Array of String task names affected by the command.
459
427
  def self.control(name, command)
460
428
  # Get the list of items.
461
- items = self.watches_by_name(name)
429
+ items = watches_by_name(name)
462
430
 
463
431
  jobs = []
464
432
 
465
433
  # Do the command.
466
434
  case command
467
- when "start", "monitor"
435
+ when 'start', 'monitor'
468
436
  items.each { |w| jobs << Thread.new { w.monitor if w.state != :up } }
469
- when "restart"
437
+ when 'restart'
470
438
  items.each { |w| jobs << Thread.new { w.move(:restart) } }
471
- when "stop"
472
- items.each { |w| jobs << Thread.new { w.action(:stop); w.unmonitor if w.state != :unmonitored } }
473
- when "unmonitor"
439
+ when 'stop'
440
+ items.each do |w|
441
+ jobs << Thread.new do
442
+ w.action(:stop)
443
+ w.unmonitor if w.state != :unmonitored
444
+ end
445
+ end
446
+ when 'unmonitor'
474
447
  items.each { |w| jobs << Thread.new { w.unmonitor if w.state != :unmonitored } }
475
- when "remove"
476
- items.each { |w| self.unwatch(w) }
448
+ when 'remove'
449
+ items.each { |w| unwatch(w) }
477
450
  else
478
- raise InvalidCommandError.new
451
+ raise InvalidCommandError
479
452
  end
480
453
 
481
- jobs.each { |j| j.join }
454
+ jobs.each(&:join)
482
455
 
483
- items.map { |x| x.name }
456
+ items.map(&:name)
484
457
  end
485
458
 
486
459
  # Unmonitor and stop all tasks.
@@ -488,7 +461,7 @@ module God
488
461
  # Returns true on success, false if all tasks could not be stopped within 10
489
462
  # seconds
490
463
  def self.stop_all
491
- self.watches.sort.each do |name, w|
464
+ watches.sort.each do |_name, w|
492
465
  Thread.new do
493
466
  w.action(:stop)
494
467
  w.unmonitor if w.state != :unmonitored
@@ -496,11 +469,12 @@ module God
496
469
  end
497
470
 
498
471
  terminate_timeout.times do
499
- return true unless self.watches.map { |name, w| w.alive? }.any?
472
+ return true if watches.none? { |_name, w| w.alive? }
473
+
500
474
  sleep 1
501
475
  end
502
476
 
503
- return false
477
+ false
504
478
  end
505
479
 
506
480
  # Force the termination of god.
@@ -510,8 +484,8 @@ module God
510
484
  #
511
485
  # Never returns because the process will no longer exist!
512
486
  def self.terminate
513
- FileUtils.rm_f(self.pid) if self.pid
514
- self.server.stop if self.server
487
+ FileUtils.rm_f(pid) if pid
488
+ server&.stop
515
489
  exit!(0)
516
490
  end
517
491
 
@@ -526,8 +500,8 @@ module God
526
500
  # Symbol status.
527
501
  def self.status
528
502
  info = {}
529
- self.watches.map do |name, w|
530
- info[name] = { :state => w.state, :group => w.group }
503
+ watches.map do |name, w|
504
+ info[name] = { state: w.state, group: w.group }
531
505
  end
532
506
  info
533
507
  end
@@ -542,8 +516,8 @@ module God
542
516
  items = watches_by_name(name)
543
517
  jobs = []
544
518
  items.each { |w| jobs << Thread.new { w.signal(signal) } }
545
- jobs.each { |j| j.join }
546
- items.map { |x| x.name }
519
+ jobs.each(&:join)
520
+ items.map(&:name)
547
521
  end
548
522
 
549
523
  # Log lines for the given task since the specified time.
@@ -554,11 +528,9 @@ module God
554
528
  # Raises God::NoSuchWatchError if no tasks matched.
555
529
  # Returns the String of newline separated log lines.
556
530
  def self.running_log(watch_name, since)
557
- matches = pattern_match(watch_name, self.watches.keys)
531
+ matches = pattern_match(watch_name, watches.keys)
558
532
 
559
- unless matches.first
560
- raise NoSuchWatchError.new
561
- end
533
+ raise NoSuchWatchError unless matches.first
562
534
 
563
535
  LOG.watch_log_since(matches.first, since)
564
536
  end
@@ -581,7 +553,7 @@ module God
581
553
  # from the system (if 'remove' or 'stop' was
582
554
  # specified as the action).
583
555
  def self.running_load(code, filename, action = nil)
584
- errors = ""
556
+ errors = ''
585
557
  loaded_watches = []
586
558
  unloaded_watches = []
587
559
  jobs = []
@@ -590,27 +562,30 @@ module God
590
562
  LOG.start_capture
591
563
 
592
564
  Gem.clear_paths
593
- eval(code, root_binding, filename)
594
- self.pending_watches.each do |w|
595
- if previous_state = self.pending_watch_states[w.name]
565
+ eval(code, root_binding, filename) # rubocop:disable Security/Eval
566
+ pending_watches.each do |w|
567
+ if (previous_state = pending_watch_states[w.name])
596
568
  w.monitor unless previous_state == :unmonitored
597
- else
598
- w.monitor if w.autostart?
569
+ elsif w.autostart?
570
+ w.monitor
599
571
  end
600
572
  end
601
- loaded_watches = self.pending_watches.map { |w| w.name }
602
- self.pending_watches.clear
603
- self.pending_watch_states.clear
573
+ loaded_watches = pending_watches.map(&:name)
574
+ pending_watches.clear
575
+ pending_watch_states.clear
604
576
 
605
- self.watches.each do |name, watch|
577
+ watches.each do |name, watch|
606
578
  next if loaded_watches.include?(name)
607
579
 
608
580
  case action
609
581
  when 'stop'
610
- jobs << Thread.new(watch) { |w| w.action(:stop); self.unwatch(w) }
582
+ jobs << Thread.new(watch) do |w|
583
+ w.action(:stop)
584
+ unwatch(w)
585
+ end
611
586
  unloaded_watches << name
612
587
  when 'remove'
613
- jobs << Thread.new(watch) { |w| self.unwatch(w) }
588
+ jobs << Thread.new(watch) { |w| unwatch(w) }
614
589
  unloaded_watches << name
615
590
  when 'leave', '', nil
616
591
  # Do nothing
@@ -631,7 +606,7 @@ module God
631
606
  end
632
607
  end
633
608
 
634
- jobs.each { |t| t.join }
609
+ jobs.each(&:join)
635
610
 
636
611
  [loaded_watches, errors, unloaded_watches]
637
612
  end
@@ -651,19 +626,19 @@ module God
651
626
  #
652
627
  # Returns nothing.
653
628
  def self.setup
654
- if self.pid_file_directory
629
+ if pid_file_directory
630
+ dir = File.expand_path(pid_file_directory)
655
631
  # Pid file dir was specified, ensure it is created and writable.
656
- unless File.exist?(self.pid_file_directory)
632
+ unless File.exist?(dir)
657
633
  begin
658
- FileUtils.mkdir_p(self.pid_file_directory)
659
- rescue Errno::EACCES => e
634
+ FileUtils.mkdir_p(dir)
635
+ rescue Errno::EACCES => e # rubocop:disable Metrics/BlockNesting
660
636
  abort "Failed to create pid file directory: #{e.message}"
661
637
  end
662
638
  end
639
+ abort "The pid file directory (#{dir}) is not writable by #{Etc.getlogin}" unless File.writable?(dir)
663
640
 
664
- unless File.writable?(self.pid_file_directory)
665
- abort "The pid file directory (#{self.pid_file_directory}) is not writable by #{Etc.getlogin}"
666
- end
641
+ self.pid_file_directory = dir
667
642
  else
668
643
  # No pid file dir specified, try defaults.
669
644
  PID_FILE_DIRECTORY_DEFAULTS.each do |idir|
@@ -674,39 +649,40 @@ module God
674
649
  self.pid_file_directory = dir
675
650
  break
676
651
  end
677
- rescue Errno::EACCES => e
652
+ rescue Errno::EACCES
653
+ # Ignore errors on directory creation failure here.
678
654
  end
679
655
  end
680
656
 
681
- unless self.pid_file_directory
657
+ unless pid_file_directory
682
658
  dirs = PID_FILE_DIRECTORY_DEFAULTS.map { |x| File.expand_path(x) }
683
659
  abort "No pid file directory exists, could be created, or is writable at any of #{dirs.join(', ')}"
684
660
  end
685
661
  end
686
662
 
687
663
  if God::Logger.syslog
688
- LOG.info("Syslog enabled.")
664
+ LOG.info('Syslog enabled.')
689
665
  else
690
- LOG.info("Syslog disabled.")
666
+ LOG.info('Syslog disabled.')
691
667
  end
692
668
 
693
- applog(nil, :info, "Using pid file directory: #{self.pid_file_directory}")
669
+ applog(nil, :info, "Using pid file directory: #{pid_file_directory}")
694
670
  end
695
671
 
696
672
  # Initialize and startup the machinery that makes god work.
697
673
  #
698
674
  # Returns nothing.
699
675
  def self.start
700
- self.internal_init
676
+ internal_init
701
677
 
702
678
  # Instantiate server.
703
- self.server = Socket.new(self.port, self.socket_user, self.socket_group, self.socket_perms)
679
+ self.server = Socket.new(self.port, socket_user, socket_group, socket_perms)
704
680
 
705
681
  # Start monitoring any watches set to autostart.
706
- self.watches.values.each { |w| w.monitor if w.autostart? }
682
+ watches.each_value { |w| w.monitor if w.autostart? }
707
683
 
708
684
  # Clear pending watches.
709
- self.pending_watches.clear
685
+ pending_watches.clear
710
686
 
711
687
  # Mark as running.
712
688
  self.running = true
@@ -724,7 +700,7 @@ module God
724
700
  #
725
701
  # Returns nothing.
726
702
  def self.join
727
- self.main.join if self.main
703
+ main&.join
728
704
  end
729
705
 
730
706
  # Returns the version String.
@@ -736,8 +712,8 @@ module God
736
712
  #
737
713
  # Returns nothing.
738
714
  def self.at_exit
739
- self.start
740
- self.join
715
+ start
716
+ join
741
717
  end
742
718
 
743
719
  # private
@@ -758,11 +734,9 @@ module God
758
734
  #
759
735
  # Returns the Array of matching name Strings.
760
736
  def self.pattern_match(pattern, list)
761
- regex = pattern.split('').join('.*')
737
+ regex = pattern.chars.join('.*')
762
738
 
763
- list.select do |item|
764
- item =~ Regexp.new(regex)
765
- end.sort_by { |x| x.size }
739
+ list.grep(Regexp.new(regex)).sort_by(&:size)
766
740
  end
767
741
  end
768
742