legionio 0.2.0 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. metadata +22 -104
  3. data/.circleci/config.yml +0 -98
  4. data/.gitignore +0 -14
  5. data/.rspec +0 -2
  6. data/.rubocop.yml +0 -56
  7. data/CHANGELOG.md +0 -7
  8. data/Gemfile +0 -15
  9. data/LICENSE.txt +0 -21
  10. data/README.md +0 -46
  11. data/Rakefile +0 -38
  12. data/bin/console +0 -16
  13. data/bin/legion +0 -61
  14. data/bin/setup +0 -8
  15. data/bin/test +0 -32
  16. data/bitbucket-pipelines.yml +0 -55
  17. data/exe/legion +0 -58
  18. data/legion.gemspec +0 -60
  19. data/lib/legion.rb +0 -21
  20. data/lib/legion/exceptions/handled_task.rb +0 -6
  21. data/lib/legion/exceptions/invalidjson.rb +0 -8
  22. data/lib/legion/exceptions/missingargument.rb +0 -8
  23. data/lib/legion/exceptions/wrongtype.rb +0 -10
  24. data/lib/legion/exceptions/wrongtypes/array.rb +0 -11
  25. data/lib/legion/exceptions/wrongtypes/hash.rb +0 -11
  26. data/lib/legion/exceptions/wrongtypes/integer.rb +0 -11
  27. data/lib/legion/exceptions/wrongtypes/string.rb +0 -11
  28. data/lib/legion/extensions.rb +0 -151
  29. data/lib/legion/extensions/actors/base.rb +0 -53
  30. data/lib/legion/extensions/actors/every.rb +0 -50
  31. data/lib/legion/extensions/actors/loop.rb +0 -34
  32. data/lib/legion/extensions/actors/nothing.rb +0 -15
  33. data/lib/legion/extensions/actors/once.rb +0 -42
  34. data/lib/legion/extensions/actors/poll.rb +0 -90
  35. data/lib/legion/extensions/actors/subscription.rb +0 -120
  36. data/lib/legion/extensions/builders/actors.rb +0 -62
  37. data/lib/legion/extensions/builders/base.rb +0 -38
  38. data/lib/legion/extensions/builders/helpers.rb +0 -26
  39. data/lib/legion/extensions/builders/runners.rb +0 -54
  40. data/lib/legion/extensions/core.rb +0 -84
  41. data/lib/legion/extensions/helpers/base.rb +0 -88
  42. data/lib/legion/extensions/helpers/core.rb +0 -20
  43. data/lib/legion/extensions/helpers/lex.rb +0 -22
  44. data/lib/legion/extensions/helpers/logger.rb +0 -48
  45. data/lib/legion/extensions/helpers/task.rb +0 -42
  46. data/lib/legion/extensions/helpers/transport.rb +0 -45
  47. data/lib/legion/extensions/transport.rb +0 -156
  48. data/lib/legion/process.rb +0 -138
  49. data/lib/legion/runner.rb +0 -57
  50. data/lib/legion/runner/log.rb +0 -12
  51. data/lib/legion/runner/status.rb +0 -72
  52. data/lib/legion/service.rb +0 -80
  53. data/lib/legion/supervison.rb +0 -14
  54. data/lib/legion/version.rb +0 -5
  55. data/settings/client.json +0 -9
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'base'
4
- module Legion
5
- module Extensions
6
- module Helpers
7
- module Core
8
- include Legion::Extensions::Helpers::Base
9
-
10
- def settings
11
- if Legion::Settings[:extensions].key?(lex_filename.to_sym)
12
- Legion::Settings[:extensions][lex_filename.to_sym]
13
- else
14
- { logger: { level: 'info', extended: false } }
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Legion
4
- module Extensions
5
- module Helpers
6
- module Lex
7
- include Legion::Extensions::Helpers::Core
8
- include Legion::Extensions::Helpers::Logger
9
-
10
- def self.included(base)
11
- base.send :extend, Legion::Extensions::Helpers::Core if base.class == Class
12
- base.send :extend, Legion::Extensions::Helpers::Logger if base.class == Class
13
- base.extend base if base.class == Module
14
- end
15
-
16
- def default_settings
17
- { logger: { level: 'info' } }
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Legion
4
- module Extensions
5
- module Helpers
6
- module Logger
7
- def log
8
- return @log unless @log.nil?
9
-
10
- logger_hash = { lex: lex_filename || nil }
11
- logger_hash[:lex] = lex_filename.first if logger_hash[:lex].is_a? Array
12
- if respond_to?(:settings) && settings.key?(:logger)
13
- logger_hash[:level] = settings[:logger][:level] if settings[:logger].key? :level
14
- logger_hash[:level] = settings[:logger][:log_file] if settings[:logger].key? :log_file
15
- logger_hash[:trace] = settings[:logger][:trace] if settings[:logger].key? :trace
16
- logger_hash[:extended] = settings[:logger][:extended] if settings[:logger].key? :extended
17
- elsif respond_to?(:settings)
18
- Legion::Logging.warn Legion::Settings[:extensions][lex_filename.to_sym]
19
- Legion::Logging.warn "#{lex_name} has settings but no :logger key"
20
- else
21
- Legion::Logging.warn 'no settings'
22
- end
23
- @log = Legion::Logging::Logger.new(logger_hash)
24
- end
25
-
26
- def handle_exception(exception, task_id: nil, **opts)
27
- log.error exception.message + " for task_id: #{task_id} but was logged "
28
- log.error exception.backtrace[0..10]
29
- log.error opts
30
-
31
- unless task_id.nil?
32
- Legion::Transport::Messages::TaskLog.new(
33
- task_id: task_id,
34
- runner_class: to_s,
35
- entry: {
36
- exception: true,
37
- message: exception.message,
38
- **opts
39
- }
40
- ).publish
41
- end
42
-
43
- raise Legion::Exception::HandledTask
44
- end
45
- end
46
- end
47
- end
48
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'legion/transport'
4
- require 'legion/transport/messages/task_update'
5
- require 'legion/transport/messages/task_log'
6
-
7
- module Legion
8
- module Extensions
9
- module Helpers
10
- module Task
11
- def generate_task_log(task_id:, runner_class: to_s, function:, **payload)
12
- Legion::Transport::Messages::TaskLog.new(task_id: task_id, runner_class: runner_class, function: function, entry: payload).publish
13
- end
14
-
15
- def task_update(task_id, status, **opts)
16
- return if task_id.nil? || status.nil?
17
-
18
- update_hash = { task_id: task_id, status: status }
19
- %i[results payload function_args payload results].each do |column|
20
- update_hash[column] = opts[column] if opts.key? column
21
- end
22
- Legion::Transport::Messages::TaskUpdate.new(update_hash).publish
23
- rescue StandardError => e
24
- log.fatal e.message
25
- log.fatal e.backtrace
26
- raise e
27
- end
28
-
29
- def generate_task_id(function_id:, status: 'task.queued', **opts)
30
- insert = { status: status, function_id: function_id }
31
- insert[:payload] = Legion::JSON.dump(opts[:payload]) if opts.key? :payload
32
- insert[:function_args] = Legion::JSON.dump(opts[:args]) if opts.key? :args
33
- %i[master_id parent_id relationship_id task_id].each do |column|
34
- insert[column] = opts[column] if opts.key? column
35
- end
36
-
37
- { success: true, task_id: Legion::Data::Model::Task.insert(insert), **insert }
38
- end
39
- end
40
- end
41
- end
42
- end
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'base'
4
-
5
- module Legion
6
- module Extensions
7
- module Helpers
8
- module Transport
9
- include Legion::Extensions::Helpers::Base
10
-
11
- def transport_path
12
- @transport_path ||= "#{full_path}/transport"
13
- end
14
-
15
- def transport_class
16
- @transport_class ||= lex_class::Transport
17
- end
18
-
19
- def messages
20
- @messages ||= transport_class::Messages
21
- end
22
-
23
- def queues
24
- @queues ||= transport_class::Queues
25
- end
26
-
27
- def exchanges
28
- @exchanges ||= transport_class::Exchanges
29
- end
30
-
31
- def default_exchange
32
- @default_exchange ||= build_default_exchange
33
- end
34
-
35
- def build_default_exchange
36
- exchange = "#{transport_class}::Exchanges::#{lex_const}"
37
- return Object.const_get(exchange) if transport_class::Exchanges.const_defined? lex_const
38
-
39
- transport_class::Exchanges.const_set(lex_const, Class.new(Legion::Transport::Exchange))
40
- @default_exchange = Kernel.const_get(exchange)
41
- end
42
- end
43
- end
44
- end
45
- end
@@ -1,156 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Legion
4
- module Extensions
5
- module Transport
6
- include Legion::Extensions::Helpers::Transport
7
-
8
- attr_accessor :exchanges, :queues, :consumers, :messages
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)
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
- Kernel.const_set(queue, Class.new(Legion::Transport::Queue))
67
- end
68
-
69
- def auto_create_dlx_exchange
70
- return if transport_class::Exchanges.const_defined? 'Dlx'
71
-
72
- dlx = transport_class::Exchanges.const_set('Dlx', Class.new(default_exchange) do
73
- def exchange_name
74
- "#{super}.dlx"
75
- end
76
- end)
77
- dlx.new
78
- dlx
79
- end
80
-
81
- def auto_create_dlx_queue
82
- return if transport_class::Queues.const_defined?('Dlx')
83
-
84
- special_name = default_exchange.new.exchange_name
85
- dlx_queue = Legion::Transport::Queue.new "#{special_name}.dlx"
86
- dlx_queue.bind("#{special_name}.dlx", { routing_key: '#' })
87
- end
88
-
89
- def build_e_to_q(array)
90
- array.each do |binding|
91
- binding[:routing_key] = nil unless binding.key? :routing_key
92
- binding[:to] = nil unless binding.key? :to
93
- bind_e_to_q(**binding)
94
- end
95
- end
96
-
97
- def bind_e_to_q(to:, from: default_exchange, routing_key: nil)
98
- if from.is_a? String
99
- from = "#{transport_class}::Exchanges::#{from.split('_').collect(&:capitalize).join}" unless from.include?('::')
100
- auto_create_exchange(from) unless Object.const_defined? from
101
- end
102
-
103
- if to.is_a? String
104
- to = "#{transport_class}::Queues::#{to.split('_').collect(&:capitalize).join}" unless to.include?('::')
105
- auto_create_queue(to) unless Object.const_defined?(to)
106
- end
107
-
108
- routing_key = to.to_s.split('::').last.downcase if routing_key.nil?
109
- bind(from, to, routing_key: routing_key)
110
- end
111
-
112
- def build_e_to_e
113
- e_to_e.each do |binding|
114
- if binding[:from].is_a? String
115
- binding[:from] = "#{transport_class}::Exchanges::#{binding[:from].capitalize}" unless binding[:from].include?('::')
116
- auto_create_exchange(binding[:from]) unless Object.const_defined? binding[:from]
117
- end
118
-
119
- if binding[:to].is_a? String
120
- binding[:to] = "#{transport_class}::Exchanges::#{binding[:to].capitalize}" unless binding[:to].include?('::')
121
- auto_create_exchange(binding[:to]) unless Object.const_defined? binding[:to]
122
- end
123
-
124
- bind(binding[:from], binding[:to], binding)
125
- end
126
- end
127
-
128
- def bind(from, to, routing_key: nil, **_options)
129
- from = from.is_a?(String) ? Kernel.const_get(from).new : from.new
130
- to = to.is_a?(String) ? Kernel.const_get(to).new : to.new
131
- to.bind(from, routing_key: routing_key)
132
- rescue StandardError => e
133
- Legion::Logging.fatal e.message
134
- Legion::Logging.fatal e.backtrace
135
- Legion::Logging.fatal({ from: from, to: to, routing_key: routing_key })
136
- end
137
-
138
- def e_to_q
139
- [] if !@exchanges.count != 1
140
- auto = []
141
- @queues.each do |queue|
142
- auto.push(from: @exchanges.first, to: queue, routing_key: queue)
143
- end
144
- auto
145
- end
146
-
147
- def e_to_e
148
- []
149
- end
150
-
151
- def additional_e_to_q
152
- []
153
- end
154
- end
155
- end
156
- end
@@ -1,138 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'fileutils'
4
-
5
- module Legion
6
- # Responsible for starting the Legion process
7
- class Process
8
- def self.run!(options)
9
- Legion::Process.new(options).run!
10
- end
11
-
12
- attr_reader :options, :quit, :service
13
-
14
- def initialize(options)
15
- @options = options
16
- options[:logfile] = File.expand_path(logfile) if logfile?
17
- options[:pidfile] = File.expand_path(pidfile) if pidfile?
18
- end
19
-
20
- def daemonize?
21
- options[:daemonize]
22
- end
23
-
24
- def logfile
25
- options[:logfile]
26
- end
27
-
28
- def pidfile
29
- options[:pidfile]
30
- end
31
-
32
- def logfile?
33
- !logfile.nil?
34
- end
35
-
36
- def pidfile?
37
- !pidfile.nil?
38
- end
39
-
40
- def info(msg)
41
- puts "[#{::Process.pid}] [#{Time.now}] #{msg}"
42
- end
43
-
44
- def run!
45
- start_time = Time.now
46
- @options[:time_limit] = @options[:time_limit].to_i if @options.key? :time_limit
47
- @quit = false
48
- check_pid
49
- daemonize if daemonize?
50
- write_pid
51
- trap_signals
52
-
53
- until quit
54
- sleep(1) # in real life, something productive would happen here
55
- if @options.key? :time_limit
56
- @quit = true if Time.now - start_time > @options[:time_limit]
57
- end
58
- end
59
- Legion::Logging.info('Legion is shutting down!')
60
- Legion.shutdown
61
- Legion::Logging.info('Legion has shutdown. Goodbye!')
62
-
63
- exit
64
- end
65
-
66
- #==========================================================================
67
- # DAEMONIZING, PID MANAGEMENT, and OUTPUT REDIRECTION
68
- #==========================================================================
69
-
70
- def daemonize
71
- exit if fork
72
- ::Process.setsid
73
- exit if fork
74
- Dir.chdir '/'
75
- end
76
-
77
- def write_pid
78
- if pidfile?
79
- begin
80
- File.open(pidfile, ::File::CREAT | ::File::EXCL | ::File::WRONLY) { |f| f.write(::Process.pid.to_s) }
81
- at_exit { File.delete(pidfile) if File.exist?(pidfile) }
82
- rescue Errno::EEXIST
83
- check_pid
84
- retry
85
- end
86
- end
87
- false
88
- end
89
-
90
- def check_pid
91
- if pidfile?
92
- case pid_status(pidfile)
93
- when :running, :not_owned
94
- exit(1)
95
- when :dead
96
- File.delete(pidfile)
97
- end
98
- end
99
- false
100
- end
101
-
102
- def pid_status(pidfile)
103
- return :exited unless File.exist?(pidfile)
104
-
105
- pid = ::File.read(pidfile).to_i
106
- return :dead if pid.zero?
107
-
108
- ::Process.kill(0, pid)
109
- :running
110
- rescue Errno::ESRCH
111
- :dead
112
- rescue Errno::EPERM
113
- :not_owned
114
- end
115
-
116
- #==========================================================================
117
- # SIGNAL HANDLING
118
- #==========================================================================
119
-
120
- def trap_signals
121
- # trap(:QUIT) do # graceful shutdown
122
- # info 'shutting down'
123
- # @quit = true
124
- # end
125
-
126
- trap('SIGTERM') do
127
- info 'sigterm'
128
- end
129
-
130
- trap('SIGHUP') do
131
- info 'sithup'
132
- end
133
- trap('SIGINT') do
134
- @quit = true
135
- end
136
- end
137
- end
138
- end