legionio 0.3.3 → 0.4.2

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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +136 -0
  3. data/.gitignore +15 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +94 -0
  6. data/CHANGELOG.md +43 -0
  7. data/Dockerfile +9 -0
  8. data/Gemfile +3 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +161 -0
  11. data/Rakefile +32 -0
  12. data/bitbucket-pipelines.yml +19 -0
  13. data/docker_deploy.rb +10 -0
  14. data/exe/legion +4 -0
  15. data/exe/legionio +53 -0
  16. data/exe/lex_gen +5 -0
  17. data/legionio.gemspec +64 -0
  18. data/lib/legion.rb +25 -0
  19. data/lib/legion/cli.rb +56 -0
  20. data/lib/legion/cli/chain.rb +35 -0
  21. data/lib/legion/cli/cohort.rb +10 -0
  22. data/lib/legion/cli/function.rb +41 -0
  23. data/lib/legion/cli/lex/actor.rb +31 -0
  24. data/lib/legion/cli/lex/exchange.rb +32 -0
  25. data/lib/legion/cli/lex/message.rb +32 -0
  26. data/lib/legion/cli/lex/queue.rb +45 -0
  27. data/lib/legion/cli/lex/runner.rb +70 -0
  28. data/lib/legion/cli/lex/templates/actor.erb +6 -0
  29. data/lib/legion/cli/lex/templates/actor_spec.erb +0 -0
  30. data/lib/legion/cli/lex/templates/base/bitbucket.yml.erb +69 -0
  31. data/lib/legion/cli/lex/templates/base/gemfile.erb +3 -0
  32. data/lib/legion/cli/lex/templates/base/gemspec.erb +26 -0
  33. data/lib/legion/cli/lex/templates/base/gitignore.erb +11 -0
  34. data/lib/legion/cli/lex/templates/base/lex.erb +9 -0
  35. data/lib/legion/cli/lex/templates/base/lex_spec.erb +5 -0
  36. data/lib/legion/cli/lex/templates/base/lic.erb +21 -0
  37. data/lib/legion/cli/lex/templates/base/rakefile.erb +6 -0
  38. data/lib/legion/cli/lex/templates/base/readme.md.erb +2 -0
  39. data/lib/legion/cli/lex/templates/base/rubocop.yml.erb +15 -0
  40. data/lib/legion/cli/lex/templates/base/spec_helper.rb.erb +11 -0
  41. data/lib/legion/cli/lex/templates/base/version.erb +7 -0
  42. data/lib/legion/cli/lex/templates/exchange.erb +11 -0
  43. data/lib/legion/cli/lex/templates/exchange_spec.erb +0 -0
  44. data/lib/legion/cli/lex/templates/message.erb +23 -0
  45. data/lib/legion/cli/lex/templates/message_spec.erb +0 -0
  46. data/lib/legion/cli/lex/templates/queue.erb +12 -0
  47. data/lib/legion/cli/lex/templates/queue_helper.erb +24 -0
  48. data/lib/legion/cli/lex/templates/queue_spec.erb +11 -0
  49. data/lib/legion/cli/lex/templates/runner.erb +11 -0
  50. data/lib/legion/cli/lex/templates/runner_spec.erb +11 -0
  51. data/lib/legion/cli/relationship.rb +22 -0
  52. data/lib/legion/cli/task.rb +49 -0
  53. data/lib/legion/cli/trigger.rb +88 -0
  54. data/lib/legion/cli/version.rb +5 -0
  55. data/lib/legion/extensions.rb +219 -0
  56. data/lib/legion/extensions/actors/base.rb +47 -0
  57. data/lib/legion/extensions/actors/every.rb +48 -0
  58. data/lib/legion/extensions/actors/loop.rb +32 -0
  59. data/lib/legion/extensions/actors/nothing.rb +15 -0
  60. data/lib/legion/extensions/actors/once.rb +40 -0
  61. data/lib/legion/extensions/actors/poll.rb +87 -0
  62. data/lib/legion/extensions/actors/subscription.rb +139 -0
  63. data/lib/legion/extensions/builders/actors.rb +61 -0
  64. data/lib/legion/extensions/builders/base.rb +36 -0
  65. data/lib/legion/extensions/builders/helpers.rb +24 -0
  66. data/lib/legion/extensions/builders/runners.rb +58 -0
  67. data/lib/legion/extensions/core.rb +131 -0
  68. data/lib/legion/extensions/data.rb +58 -0
  69. data/lib/legion/extensions/data/migrator.rb +28 -0
  70. data/lib/legion/extensions/data/model.rb +8 -0
  71. data/lib/legion/extensions/helpers/base.rb +82 -0
  72. data/lib/legion/extensions/helpers/cache.rb +23 -0
  73. data/lib/legion/extensions/helpers/core.rb +41 -0
  74. data/lib/legion/extensions/helpers/data.rb +23 -0
  75. data/lib/legion/extensions/helpers/lex.rb +48 -0
  76. data/lib/legion/extensions/helpers/logger.rb +44 -0
  77. data/lib/legion/extensions/helpers/task.rb +60 -0
  78. data/lib/legion/extensions/helpers/transport.rb +44 -0
  79. data/lib/legion/extensions/transport.rb +159 -0
  80. data/lib/legion/lex.rb +89 -0
  81. data/lib/legion/process.rb +124 -0
  82. data/lib/legion/runner.rb +55 -0
  83. data/lib/legion/runner/log.rb +10 -0
  84. data/lib/legion/runner/status.rb +69 -0
  85. data/lib/legion/service.rb +130 -0
  86. data/lib/legion/supervision.rb +15 -0
  87. data/lib/legion/version.rb +3 -0
  88. metadata +243 -39
@@ -0,0 +1,44 @@
1
+ module Legion
2
+ module Extensions
3
+ module Helpers
4
+ module Logger
5
+ def log
6
+ return @log unless @log.nil?
7
+
8
+ logger_hash = { lex: lex_filename || nil }
9
+ logger_hash[:lex] = lex_filename.first if logger_hash[:lex].is_a? Array
10
+ if respond_to?(:settings) && settings.key?(:logger)
11
+ logger_hash[:level] = settings[:logger].key?(:level) ? settings[:logger][:level] : 'info'
12
+ logger_hash[:log_file] = settings[:logger][:log_file] if settings[:logger].key? :log_file
13
+ logger_hash[:trace] = settings[:logger][:trace] if settings[:logger].key? :trace
14
+ logger_hash[:extended] = settings[:logger][:extended] if settings[:logger].key? :extended
15
+ elsif respond_to?(:settings)
16
+ Legion::Logging.warn Legion::Settings[:extensions][lex_filename.to_sym]
17
+ Legion::Logging.warn "#{lex_name} has settings but no :logger key"
18
+ end
19
+ @log = Legion::Logging::Logger.new(**logger_hash)
20
+ end
21
+
22
+ def handle_exception(exception, task_id: nil, **opts)
23
+ log.error exception.message + " for task_id: #{task_id} but was logged "
24
+ log.error exception.backtrace[0..10]
25
+ log.error opts
26
+
27
+ unless task_id.nil?
28
+ Legion::Transport::Messages::TaskLog.new(
29
+ task_id: task_id,
30
+ runner_class: to_s,
31
+ entry: {
32
+ exception: true,
33
+ message: exception.message,
34
+ **opts
35
+ }
36
+ ).publish
37
+ end
38
+
39
+ raise Legion::Exception::HandledTask
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,60 @@
1
+ require 'legion/transport'
2
+ require 'legion/transport/messages/task_update'
3
+ require 'legion/transport/messages/task_log'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Helpers
8
+ module Task
9
+ def generate_task_log(task_id:, function:, runner_class: to_s, **payload)
10
+ begin
11
+ if Legion::Settings[:data][:connected]
12
+ runner_id = Legion::Data::Model::Runner[namespace: runner_class].values[:id]
13
+ function_id = Legion::Data::Model::Function.where(runner_id: runner_id, name: function).first.values[:id]
14
+ return true if Legion::Data::Model::TaskLog.insert(task_id: task_id, function_id: function_id, entry: Legion::JSON.dump(payload))
15
+ end
16
+ rescue StandardError => e
17
+ log.warn e.backtrace
18
+ log.warn("generate_task_log failed, reverting to rmq message, e: #{e.message}")
19
+ end
20
+ Legion::Transport::Messages::TaskLog.new(task_id: task_id, runner_class: runner_class, function: function, entry: payload).publish
21
+ end
22
+
23
+ def task_update(task_id, status, **opts)
24
+ return if task_id.nil? || status.nil?
25
+
26
+ begin
27
+ if Legion::Settings[:data][:connected]
28
+ task = Legion::Data::Model::Task[task_id]
29
+ task.update(status: status)
30
+ return true
31
+ end
32
+ rescue StandardError => e
33
+ log.debug("task_update failed, reverting to rmq message, e: #{e.message}")
34
+ end
35
+
36
+ update_hash = { task_id: task_id, status: status }
37
+ %i[results payload function_args payload results].each do |column|
38
+ update_hash[column] = opts[column] if opts.key? column
39
+ end
40
+ Legion::Transport::Messages::TaskUpdate.new(**update_hash).publish
41
+ rescue StandardError => e
42
+ log.fatal e.message
43
+ log.fatal e.backtrace
44
+ raise e
45
+ end
46
+
47
+ def generate_task_id(function_id:, status: 'task.queued', **opts)
48
+ insert = { status: status, function_id: function_id }
49
+ insert[:payload] = Legion::JSON.dump(opts[:payload]) if opts.key? :payload
50
+ insert[:function_args] = Legion::JSON.dump(opts[:args]) if opts.key? :args
51
+ %i[master_id parent_id relationship_id task_id].each do |column|
52
+ insert[column] = opts[column] if opts.key? column
53
+ end
54
+
55
+ { success: true, task_id: Legion::Data::Model::Task.insert(insert), **insert }
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,44 @@
1
+ require_relative 'base'
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Helpers
6
+ module Transport
7
+ include Legion::Extensions::Helpers::Base
8
+
9
+ def transport_path
10
+ @transport_path ||= "#{full_path}/transport"
11
+ end
12
+
13
+ def transport_class
14
+ @transport_class ||= lex_class::Transport
15
+ end
16
+
17
+ def messages
18
+ @messages ||= transport_class::Messages
19
+ end
20
+
21
+ def queues
22
+ @queues ||= transport_class::Queues
23
+ end
24
+
25
+ def exchanges
26
+ @exchanges ||= transport_class::Exchanges
27
+ end
28
+
29
+ def default_exchange
30
+ @default_exchange ||= build_default_exchange
31
+ end
32
+
33
+ def build_default_exchange
34
+ exchange = "#{transport_class}::Exchanges::#{lex_const}"
35
+ return Object.const_get(exchange) if transport_class::Exchanges.const_defined? lex_const
36
+
37
+ transport_class::Exchanges.const_set(lex_const, Class.new(Legion::Transport::Exchange))
38
+ @default_exchange = Kernel.const_get(exchange)
39
+ @default_exchange
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,159 @@
1
+ module Legion
2
+ module Extensions
3
+ module Transport
4
+ include Legion::Extensions::Helpers::Transport
5
+ include Legion::Extensions::Helpers::Logger
6
+
7
+ attr_accessor :exchanges, :queues, :consumers, :messages
8
+
9
+ def build
10
+ @queues = []
11
+ @exchanges = []
12
+ @messages = []
13
+ @consumers = []
14
+ generate_base_modules
15
+ require_transport_items
16
+
17
+ build_e_to_e
18
+ build_e_to_q(e_to_q)
19
+ build_e_to_q(additional_e_to_q)
20
+ auto_create_dlx_exchange
21
+ auto_create_dlx_queue
22
+ rescue StandardError => e
23
+ Legion::Logging.error e.message
24
+ Legion::Logging.error e.backtrace
25
+ end
26
+
27
+ def generate_base_modules
28
+ lex_class.const_set('Transport', Module.new) unless lex_class.const_defined?('Transport')
29
+ %w[Queues Exchanges Messages Consumers].each do |thing|
30
+ next if transport_class.const_defined? thing
31
+
32
+ transport_class.const_set(thing, Module.new)
33
+ end
34
+ end
35
+
36
+ def require_transport_items
37
+ { 'exchanges': @exchanges, 'queues': @queues, 'consumers': @consumers, 'messages': @messages }.each do |item, obj|
38
+ Dir[File.expand_path("#{transport_path}/#{item}/*.rb")].sort.each do |file|
39
+ require file
40
+ file_name = file.to_s.split('/').last.split('.').first
41
+ obj.push(file_name) unless obj.include?(file_name)
42
+ end
43
+ end
44
+ end
45
+
46
+ def auto_create_exchange(exchange, default_exchange = false) # rubocop:disable Style/OptionalBooleanParameter
47
+ if Object.const_defined? exchange
48
+ Legion::Logging.warn "#{exchange} is already defined"
49
+ return
50
+ end
51
+ return build_default_exchange if default_exchange
52
+
53
+ transport_class::Exchanges.const_set(exchange.split('::').pop, Class.new(Legion::Transport::Exchange) do
54
+ def exchange_name
55
+ self.class.ancestors.first.to_s.split('::')[5].downcase
56
+ end
57
+ end)
58
+ end
59
+
60
+ def auto_create_queue(queue)
61
+ if Kernel.const_defined?(queue)
62
+ Legion::Logging.warn "#{queue} is already defined"
63
+ return
64
+ end
65
+
66
+ transport_class::Queues.const_set(queue.split('::').last, Class.new(Legion::Transport::Queue))
67
+ end
68
+
69
+ def auto_create_dlx_exchange
70
+ dlx = if transport_class::Exchanges.const_defined? 'Dlx'
71
+ transport_class::Exchanges::Dlx
72
+ else
73
+ transport_class::Exchanges.const_set('Dlx', Class.new(default_exchange) do
74
+ def exchange_name
75
+ "#{super}.dlx"
76
+ end
77
+ end)
78
+ end
79
+
80
+ dlx.new
81
+ end
82
+
83
+ def auto_create_dlx_queue
84
+ return if transport_class::Queues.const_defined?('Dlx')
85
+
86
+ special_name = default_exchange.new.exchange_name
87
+ dlx_queue = Legion::Transport::Queue.new "#{special_name}.dlx", auto_delete: false
88
+ dlx_queue.bind("#{special_name}.dlx", { routing_key: '#' })
89
+ end
90
+
91
+ def build_e_to_q(array)
92
+ array.each do |binding|
93
+ binding[:routing_key] = nil unless binding.key? :routing_key
94
+ binding[:to] = nil unless binding.key?(:to)
95
+ binding[:from] = default_exchange if !binding.key?(:from) || binding[:from].nil?
96
+ bind_e_to_q(**binding)
97
+ end
98
+ end
99
+
100
+ def bind_e_to_q(to:, from: default_exchange, routing_key: nil, **)
101
+ if from.is_a? String
102
+ from = "#{transport_class}::Exchanges::#{from.split('_').collect(&:capitalize).join}" unless from.include?('::')
103
+ auto_create_exchange(from) unless Object.const_defined? from
104
+ end
105
+
106
+ if to.is_a? String
107
+ to = "#{transport_class}::Queues::#{to.split('_').collect(&:capitalize).join}" unless to.include?('::')
108
+ auto_create_queue(to) unless Object.const_defined?(to)
109
+ end
110
+
111
+ routing_key = to.to_s.split('::').last.downcase if routing_key.nil?
112
+ bind(from, to, routing_key: routing_key)
113
+ end
114
+
115
+ def build_e_to_e
116
+ e_to_e.each do |binding|
117
+ if binding[:from].is_a? String
118
+ binding[:from] = "#{transport_class}::Exchanges::#{binding[:from].capitalize}" unless binding[:from].include?('::')
119
+ auto_create_exchange(binding[:from]) unless Object.const_defined? binding[:from]
120
+ end
121
+
122
+ if binding[:to].is_a? String
123
+ binding[:to] = "#{transport_class}::Exchanges::#{binding[:to].capitalize}" unless binding[:to].include?('::')
124
+ auto_create_exchange(binding[:to]) unless Object.const_defined? binding[:to]
125
+ end
126
+
127
+ bind(binding[:from], binding[:to], binding)
128
+ end
129
+ end
130
+
131
+ def bind(from, to, routing_key: nil, **_options)
132
+ from = from.is_a?(String) ? Kernel.const_get(from).new : from.new
133
+ to = to.is_a?(String) ? Kernel.const_get(to).new : to.new
134
+ to.bind(from, routing_key: routing_key)
135
+ rescue StandardError => e
136
+ log.fatal e.message
137
+ log.fatal e.backtrace
138
+ log.fatal({ from: from, to: to, routing_key: routing_key })
139
+ end
140
+
141
+ def e_to_q
142
+ [] if !@exchanges.count != 1
143
+ auto = []
144
+ @queues.each do |queue|
145
+ auto.push(from: @exchanges.first, to: queue, routing_key: queue)
146
+ end
147
+ auto
148
+ end
149
+
150
+ def e_to_e
151
+ []
152
+ end
153
+
154
+ def additional_e_to_q
155
+ []
156
+ end
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,89 @@
1
+ require 'thor'
2
+ require 'legion/cli/version'
3
+ require 'legion/cli/lex/actor'
4
+ require 'legion/cli/lex/exchange'
5
+ require 'legion/cli/lex/message'
6
+ require 'legion/cli/lex/queue'
7
+ require 'legion/cli/lex/runner'
8
+
9
+ module Legion
10
+ class Cli
11
+ class LexBuilder < Thor
12
+ check_unknown_options!
13
+ include Thor::Actions
14
+
15
+ no_commands do
16
+ def lex
17
+ Dir.pwd.split('/').last.split('-').last
18
+ end
19
+ end
20
+
21
+ def self.exit_on_failure?
22
+ true
23
+ end
24
+
25
+ def self.source_root
26
+ File.dirname(__FILE__)
27
+ end
28
+
29
+ desc 'actor', 'creates and manages actors'
30
+ subcommand 'actor', Legion::Cli::Lex::Actor
31
+
32
+ desc 'exchange', 'creates and manages exchanges'
33
+ subcommand 'exchange', Legion::Cli::Lex::Exchange
34
+
35
+ desc 'messages', 'creates and manages messages'
36
+ subcommand 'message', Legion::Cli::Lex::Message
37
+
38
+ desc 'queue', 'creates and manages queues'
39
+ subcommand 'queue', Legion::Cli::Lex::Queue
40
+
41
+ desc 'runner', 'creates and manages runners'
42
+ subcommand 'runner', Legion::Cli::Lex::Runner
43
+
44
+ desc 'version', 'Display Version'
45
+ map %w[-v --version] => :version
46
+ def version
47
+ say "Legion::CLI #{Legion::Cli::VERSION}"
48
+ end
49
+
50
+ method_option rspec: true
51
+ method_option pipeline: true
52
+ method_option git_init: true
53
+ method_option bundle_install: true
54
+ desc 'create :name', 'creates a new lex'
55
+ def create(name)
56
+ if Dir.pwd.include?('lex-')
57
+ say('already inside a lex_gen, try moving to a different directory', :red)
58
+ return nil
59
+ end
60
+
61
+ vars = { filename: "lex-#{name}", class_name: name.capitalize, lex: name }
62
+ filename = vars[:filename]
63
+ template('cli/lex/templates/base/gemspec.erb', "#{filename}/#{filename}.gemspec", vars)
64
+ template('cli/lex/templates/base/gemfile.erb', "#{filename}/Gemfile", vars)
65
+ template('cli/lex/templates/base/gitignore.erb', "#{filename}/.gitignore", vars)
66
+ template('cli/lex/templates/base/lic.erb', "#{filename}/LICENSE.txt", vars)
67
+ template('cli/lex/templates/base/rakefile.erb', "#{filename}/Rakefile", vars)
68
+ template('cli/lex/templates/base/rubocop.yml.erb', "#{filename}/.rubocop.yml", vars)
69
+ template('cli/lex/templates/base/readme.md.erb', "#{filename}/README.md", **vars)
70
+ template('cli/lex/templates/base/lex.erb', "#{filename}/lib/legion/extensions/#{name}.rb", vars)
71
+ template('cli/lex/templates/base/version.erb', "#{filename}/lib/legion/extensions/#{name}/version.rb", vars)
72
+ template('cli/lex/templates/base/bitbucket.yml.erb', "#{filename}/bitbucket-pipelines.yml", vars) if options[:pipeline]
73
+ template('cli/lex/templates/base/spec_helper.rb.erb', "#{filename}/spec/spec_helper.rb", vars)
74
+ template('cli/lex/templates/base/lex_spec.erb', "#{filename}/spec/legion/#{name}_spec.rb", vars)
75
+
76
+ return if !options[:git_init] && !options[:bundle_install]
77
+
78
+ run("cd lex_gen-#{filename}")
79
+ if options[:git_init]
80
+ run('git init')
81
+ run('git add .')
82
+ run('git commit -m \'Initial commit\'')
83
+ end
84
+
85
+ run('bundle update') if options[:bundle_install]
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,124 @@
1
+ require 'fileutils'
2
+
3
+ module Legion
4
+ class Process
5
+ def self.run!(options)
6
+ Legion::Process.new(options).run!
7
+ end
8
+
9
+ attr_reader :options, :quit, :service
10
+
11
+ def initialize(options)
12
+ @options = options
13
+ options[:logfile] = File.expand_path(logfile) if logfile?
14
+ options[:pidfile] = File.expand_path(pidfile) if pidfile?
15
+ end
16
+
17
+ def daemonize?
18
+ options[:daemonize]
19
+ end
20
+
21
+ def logfile
22
+ options[:logfile]
23
+ end
24
+
25
+ def pidfile
26
+ options[:pidfile]
27
+ end
28
+
29
+ def logfile?
30
+ !logfile.nil?
31
+ end
32
+
33
+ def pidfile?
34
+ !pidfile.nil?
35
+ end
36
+
37
+ def info(msg)
38
+ puts "[#{::Process.pid}] [#{Time.now}] #{msg}"
39
+ end
40
+
41
+ def run!
42
+ start_time = Time.now
43
+ @options[:time_limit] = @options[:time_limit].to_i if @options.key? :time_limit
44
+ @quit = false
45
+ check_pid
46
+ daemonize if daemonize?
47
+ write_pid
48
+ trap_signals
49
+
50
+ until quit
51
+ sleep(1)
52
+ @quit = true if @options.key?(:time_limit) && Time.now - start_time > @options[:time_limit]
53
+ end
54
+ Legion::Logging.info('Legion is shutting down!')
55
+ Legion.shutdown
56
+ Legion::Logging.info('Legion has shutdown. Goodbye!')
57
+
58
+ exit
59
+ end
60
+
61
+ #==========================================================================
62
+ # DAEMONIZING, PID MANAGEMENT, and OUTPUT REDIRECTION
63
+ #==========================================================================
64
+
65
+ def daemonize
66
+ exit if fork
67
+ ::Process.setsid
68
+ exit if fork
69
+ Dir.chdir '/'
70
+ end
71
+
72
+ def write_pid
73
+ if pidfile?
74
+ begin
75
+ File.open(pidfile, ::File::CREAT | ::File::EXCL | ::File::WRONLY) { |f| f.write(::Process.pid.to_s) }
76
+ at_exit { File.delete(pidfile) if File.exist?(pidfile) }
77
+ rescue Errno::EEXIST
78
+ check_pid
79
+ retry
80
+ end
81
+ end
82
+ false
83
+ end
84
+
85
+ def check_pid
86
+ if pidfile?
87
+ case pid_status(pidfile)
88
+ when :running, :not_owned
89
+ exit(1)
90
+ when :dead
91
+ File.delete(pidfile)
92
+ end
93
+ end
94
+ false
95
+ end
96
+
97
+ def pid_status(pidfile)
98
+ return :exited unless File.exist?(pidfile)
99
+
100
+ pid = ::File.read(pidfile).to_i
101
+ return :dead if pid.zero?
102
+
103
+ ::Process.kill(0, pid)
104
+ :running
105
+ rescue Errno::ESRCH
106
+ :dead
107
+ rescue Errno::EPERM
108
+ :not_owned
109
+ end
110
+
111
+ def trap_signals
112
+ trap('SIGTERM') do
113
+ info 'sigterm'
114
+ end
115
+
116
+ trap('SIGHUP') do
117
+ info 'sithup'
118
+ end
119
+ trap('SIGINT') do
120
+ @quit = true
121
+ end
122
+ end
123
+ end
124
+ end