legionio 0.3.0 → 0.3.5

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. metadata +8 -60
  3. data/.circleci/config.yml +0 -119
  4. data/.gitignore +0 -14
  5. data/.rspec +0 -2
  6. data/.rubocop.yml +0 -89
  7. data/CHANGELOG.md +0 -16
  8. data/Gemfile +0 -3
  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 -50
  14. data/bin/setup +0 -8
  15. data/bin/test +0 -32
  16. data/bitbucket-pipelines.yml +0 -55
  17. data/exe/legion +0 -50
  18. data/legion.gemspec +0 -59
  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 -5
  22. data/lib/legion/exceptions/missingargument.rb +0 -6
  23. data/lib/legion/exceptions/wrongtype.rb +0 -10
  24. data/lib/legion/exceptions/wrongtypes/array.rb +0 -8
  25. data/lib/legion/exceptions/wrongtypes/hash.rb +0 -8
  26. data/lib/legion/exceptions/wrongtypes/integer.rb +0 -8
  27. data/lib/legion/exceptions/wrongtypes/string.rb +0 -8
  28. data/lib/legion/extensions.rb +0 -164
  29. data/lib/legion/extensions/actors/base.rb +0 -49
  30. data/lib/legion/extensions/actors/every.rb +0 -48
  31. data/lib/legion/extensions/actors/loop.rb +0 -32
  32. data/lib/legion/extensions/actors/nothing.rb +0 -15
  33. data/lib/legion/extensions/actors/once.rb +0 -40
  34. data/lib/legion/extensions/actors/poll.rb +0 -88
  35. data/lib/legion/extensions/actors/subscription.rb +0 -130
  36. data/lib/legion/extensions/builders/actors.rb +0 -61
  37. data/lib/legion/extensions/builders/base.rb +0 -36
  38. data/lib/legion/extensions/builders/helpers.rb +0 -24
  39. data/lib/legion/extensions/builders/runners.rb +0 -53
  40. data/lib/legion/extensions/core.rb +0 -94
  41. data/lib/legion/extensions/data.rb +0 -10
  42. data/lib/legion/extensions/helpers/base.rb +0 -82
  43. data/lib/legion/extensions/helpers/core.rb +0 -41
  44. data/lib/legion/extensions/helpers/lex.rb +0 -20
  45. data/lib/legion/extensions/helpers/logger.rb +0 -47
  46. data/lib/legion/extensions/helpers/task.rb +0 -40
  47. data/lib/legion/extensions/helpers/transport.rb +0 -43
  48. data/lib/legion/extensions/transport.rb +0 -155
  49. data/lib/legion/process.rb +0 -126
  50. data/lib/legion/runner.rb +0 -55
  51. data/lib/legion/runner/log.rb +0 -10
  52. data/lib/legion/runner/status.rb +0 -69
  53. data/lib/legion/service.rb +0 -78
  54. data/lib/legion/supervision.rb +0 -15
  55. data/lib/legion/version.rb +0 -3
  56. data/settings/client.json +0 -23
@@ -1,43 +0,0 @@
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
- end
40
- end
41
- end
42
- end
43
- end
@@ -1,155 +0,0 @@
1
- module Legion
2
- module Extensions
3
- module Transport
4
- include Legion::Extensions::Helpers::Transport
5
-
6
- attr_accessor :exchanges, :queues, :consumers, :messages
7
-
8
- def build
9
- @queues = []
10
- @exchanges = []
11
- @messages = []
12
- @consumers = []
13
- generate_base_modules
14
- require_transport_items
15
-
16
- build_e_to_e
17
- build_e_to_q(e_to_q)
18
- build_e_to_q(additional_e_to_q)
19
- auto_create_dlx_exchange
20
- auto_create_dlx_queue
21
- rescue StandardError => e
22
- Legion::Logging.error e.message
23
- Legion::Logging.error e.backtrace
24
- end
25
-
26
- def generate_base_modules
27
- lex_class.const_set('Transport', Module.new) unless lex_class.const_defined?('Transport')
28
- %w[Queues Exchanges Messages Consumers].each do |thing|
29
- next if transport_class.const_defined? thing
30
-
31
- transport_class.const_set(thing, Module.new)
32
- end
33
- end
34
-
35
- def require_transport_items
36
- { 'exchanges': @exchanges, 'queues': @queues, 'consumers': @consumers, 'messages': @messages }.each do |item, obj|
37
- Dir[File.expand_path("#{transport_path}/#{item}/*.rb")].sort.each do |file|
38
- require file
39
- file_name = file.to_s.split('/').last.split('.').first
40
- obj.push(file_name) unless obj.include?(file_name)
41
- end
42
- end
43
- end
44
-
45
- def auto_create_exchange(exchange, default_exchange = false) # rubocop:disable Style/OptionalBooleanParameter
46
- if Object.const_defined? exchange
47
- Legion::Logging.warn "#{exchange} is already defined"
48
- return
49
- end
50
- return build_default_exchange if default_exchange
51
-
52
- transport_class::Exchanges.const_set(exchange.split('::').pop, Class.new(Legion::Transport::Exchange) do
53
- def exchange_name
54
- self.class.ancestors.first.to_s.split('::')[5].downcase
55
- end
56
- end)
57
- end
58
-
59
- def auto_create_queue(queue)
60
- if Kernel.const_defined?(queue)
61
- Legion::Logging.warn "#{queue} is already defined"
62
- return
63
- end
64
-
65
- transport_class::Queues.const_set(queue.split('::').last, Class.new(Legion::Transport::Queue))
66
- end
67
-
68
- def auto_create_dlx_exchange
69
- return if transport_class::Exchanges.const_defined? 'Dlx'
70
-
71
- dlx = transport_class::Exchanges.const_set('Dlx', Class.new(default_exchange) do
72
- def exchange_name
73
- "#{super}.dlx"
74
- end
75
- end)
76
- dlx.new
77
- dlx
78
- end
79
-
80
- def auto_create_dlx_queue
81
- return if transport_class::Queues.const_defined?('Dlx')
82
-
83
- special_name = default_exchange.new.exchange_name
84
- dlx_queue = Legion::Transport::Queue.new "#{special_name}.dlx", auto_delete: false
85
- dlx_queue.bind("#{special_name}.dlx", { routing_key: '#' })
86
- end
87
-
88
- def build_e_to_q(array)
89
- array.each do |binding|
90
- binding[:routing_key] = nil unless binding.key? :routing_key
91
- binding[:to] = nil unless binding.key? :to
92
- bind_e_to_q(**binding)
93
- end
94
- end
95
-
96
- def bind_e_to_q(to:, from: default_exchange, routing_key: nil)
97
- if from.is_a? String
98
- from = "#{transport_class}::Exchanges::#{from.split('_').collect(&:capitalize).join}" unless from.include?('::')
99
- auto_create_exchange(from) unless Object.const_defined? from
100
- end
101
-
102
- if to.is_a? String
103
- to = "#{transport_class}::Queues::#{to.split('_').collect(&:capitalize).join}" unless to.include?('::')
104
- auto_create_queue(to) unless Object.const_defined?(to)
105
- end
106
-
107
- routing_key = to.to_s.split('::').last.downcase if routing_key.nil?
108
- bind(from, to, routing_key: routing_key)
109
- end
110
-
111
- def build_e_to_e
112
- e_to_e.each do |binding|
113
- if binding[:from].is_a? String
114
- binding[:from] = "#{transport_class}::Exchanges::#{binding[:from].capitalize}" unless binding[:from].include?('::')
115
- auto_create_exchange(binding[:from]) unless Object.const_defined? binding[:from]
116
- end
117
-
118
- if binding[:to].is_a? String
119
- binding[:to] = "#{transport_class}::Exchanges::#{binding[:to].capitalize}" unless binding[:to].include?('::')
120
- auto_create_exchange(binding[:to]) unless Object.const_defined? binding[:to]
121
- end
122
-
123
- bind(binding[:from], binding[:to], binding)
124
- end
125
- end
126
-
127
- def bind(from, to, routing_key: nil, **_options)
128
- from = from.is_a?(String) ? Kernel.const_get(from).new : from.new
129
- to = to.is_a?(String) ? Kernel.const_get(to).new : to.new
130
- to.bind(from, routing_key: routing_key)
131
- rescue StandardError => e
132
- Legion::Logging.fatal e.message
133
- Legion::Logging.fatal e.backtrace
134
- Legion::Logging.fatal({ from: from, to: to, routing_key: routing_key })
135
- end
136
-
137
- def e_to_q
138
- [] if !@exchanges.count != 1
139
- auto = []
140
- @queues.each do |queue|
141
- auto.push(from: @exchanges.first, to: queue, routing_key: queue)
142
- end
143
- auto
144
- end
145
-
146
- def e_to_e
147
- []
148
- end
149
-
150
- def additional_e_to_q
151
- []
152
- end
153
- end
154
- end
155
- end
@@ -1,126 +0,0 @@
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
- if @options.key? :time_limit
53
- @quit = true if Time.now - start_time > @options[:time_limit]
54
- end
55
- end
56
- Legion::Logging.info('Legion is shutting down!')
57
- Legion.shutdown
58
- Legion::Logging.info('Legion has shutdown. Goodbye!')
59
-
60
- exit
61
- end
62
-
63
- #==========================================================================
64
- # DAEMONIZING, PID MANAGEMENT, and OUTPUT REDIRECTION
65
- #==========================================================================
66
-
67
- def daemonize
68
- exit if fork
69
- ::Process.setsid
70
- exit if fork
71
- Dir.chdir '/'
72
- end
73
-
74
- def write_pid
75
- if pidfile?
76
- begin
77
- File.open(pidfile, ::File::CREAT | ::File::EXCL | ::File::WRONLY) { |f| f.write(::Process.pid.to_s) }
78
- at_exit { File.delete(pidfile) if File.exist?(pidfile) }
79
- rescue Errno::EEXIST
80
- check_pid
81
- retry
82
- end
83
- end
84
- false
85
- end
86
-
87
- def check_pid
88
- if pidfile?
89
- case pid_status(pidfile)
90
- when :running, :not_owned
91
- exit(1)
92
- when :dead
93
- File.delete(pidfile)
94
- end
95
- end
96
- false
97
- end
98
-
99
- def pid_status(pidfile)
100
- return :exited unless File.exist?(pidfile)
101
-
102
- pid = ::File.read(pidfile).to_i
103
- return :dead if pid.zero?
104
-
105
- ::Process.kill(0, pid)
106
- :running
107
- rescue Errno::ESRCH
108
- :dead
109
- rescue Errno::EPERM
110
- :not_owned
111
- end
112
-
113
- def trap_signals
114
- trap('SIGTERM') do
115
- info 'sigterm'
116
- end
117
-
118
- trap('SIGHUP') do
119
- info 'sithup'
120
- end
121
- trap('SIGINT') do
122
- @quit = true
123
- end
124
- end
125
- end
126
- end
@@ -1,55 +0,0 @@
1
- require 'legion/exceptions/handled_task'
2
- require_relative 'runner/log'
3
- require_relative 'runner/status'
4
- require 'legion/transport'
5
- require 'legion/transport/messages/check_subtask'
6
-
7
- module Legion
8
- module Runner
9
- def self.run(runner_class:, function:, task_id: nil, args: nil, check_subtask: true, generate_task: true, parent_id: nil, master_id: nil, **opts) # rubocop:disable Metrics/ParameterLists
10
- runner_class = Kernel.const_get(runner_class) if runner_class.is_a? String
11
-
12
- if task_id.nil? && generate_task
13
- task_gen = Legion::Runner::Status.generate_task_id(
14
- function: function,
15
- runner_class: runner_class,
16
- parent_id: parent_id, master_id: master_id, task_id: task_id, **opts
17
- )
18
- task_id = task_gen[:task_id] unless task_gen.nil?
19
- end
20
-
21
- args = opts if args.nil?
22
- args[:task_id] = task_id unless task_id.nil?
23
- args[:master_id] = master_id unless master_id.nil?
24
- args[:parent_id] = parent_id unless parent_id.nil?
25
-
26
- result = runner_class.send(function, **args)
27
- rescue Legion::Exception::HandledTask
28
- status = 'task.exception'
29
- result = { error: {} }
30
- rescue StandardError => e
31
- runner_class.handle_exception(e,
32
- **opts,
33
- runner_class: runner_class,
34
- args: args,
35
- function: function,
36
- task_id: task_id,
37
- generate_task: generate_task,
38
- check_subtask: check_subtask)
39
- status = 'task.exception'
40
- result = { success: false, status: status, error: { message: e.message, backtrace: e.backtrace } }
41
- else
42
- status = 'task.completed'
43
- ensure
44
- Legion::Runner::Status.update(task_id: task_id, status: status) unless task_id.nil?
45
- if check_subtask && status == 'task.completed'
46
- Legion::Transport::Messages::CheckSubtask.new(runner_class: runner_class,
47
- function: function,
48
- result: result,
49
- original_args: args,
50
- **opts).publish
51
- end
52
- return { success: true, status: status, result: result, task_id: task_id } # rubocop:disable Lint/EnsureReturn
53
- end
54
- end
55
- end
@@ -1,10 +0,0 @@
1
- module Legion
2
- module Runner
3
- module Log
4
- def self.exception(exc, **opts)
5
- Legion::Logging.error exc.message
6
- Legion::Logging.error opts
7
- end
8
- end
9
- end
10
- end
@@ -1,69 +0,0 @@
1
- module Legion
2
- module Runner
3
- module Status
4
- def self.update(task_id:, status: 'task.completed', **opts)
5
- Legion::Logging.debug "Legion::Runner::Status.update called, #{task_id}, status: #{status}, #{opts}"
6
- return if status.nil?
7
-
8
- if Legion::Settings[:data][:connected]
9
- update_db(task_id: task_id, status: status, **opts)
10
- else
11
- update_rmq(task_id: task_id, status: status, **opts)
12
- end
13
- end
14
-
15
- def self.update_rmq(task_id:, status: 'task.completed', **opts)
16
- return if status.nil?
17
-
18
- Legion::Transport::Messages::TaskUpdate.new(task_id: task_id, status: status, **opts).publish
19
- rescue StandardError => e
20
- Legion::Logging.fatal e.message
21
- Legion::Logging.fatal e.backtrace
22
- retries ||= 0
23
- Legion::Logging.fatal 'Will retry in 3 seconds' if retries < 5
24
- sleep(3)
25
- retry if (retries += 1) < 5
26
- end
27
-
28
- def self.update_db(task_id:, status: 'task.completed', **opts)
29
- return if status.nil?
30
-
31
- task = Legion::Data::Model::Task[task_id]
32
- task.update(status: status)
33
- rescue StandardError => e
34
- Legion::Logging.warn e.message
35
- Legion::Logging.warn 'Legion::Runner.update_status_db failed, defaulting to rabbitmq'
36
- Legion::Logging.warn e.backtrace
37
- update_rmq(task_id: task_id, status: status, **opts)
38
- end
39
-
40
- def self.generate_task_id(runner_class:, function:, status: 'task.queued', **opts)
41
- Legion::Logging.debug "Legion::Runner::Status.generate_task_id called, #{runner_class}, #{function}, status: #{status}, #{opts}"
42
- return nil unless Legion::Settings[:data][:connected]
43
-
44
- runner = Legion::Data::Model::Runner.where(namespace: runner_class.to_s.downcase).first
45
- return nil if runner.nil?
46
-
47
- function = Legion::Data::Model::Function.where(runner_id: runner.values[:id], name: function).first
48
- return nil if function.nil?
49
-
50
- insert = { status: status, function_id: function.values[:id] }
51
- insert[:parent_id] = opts[:task_id] if opts.key? :task_id
52
- insert[:master_id] = opts[:task_id] if opts.key? :task_id
53
- insert[:payload] = Legion::JSON.dump(opts[:payload]) if opts.key? :payload
54
-
55
- %i[function_args master_id parent_id relationship_id].each do |column|
56
- next unless opts.key? column
57
-
58
- insert[column] = opts[column].is_a?(Hash) ? Legion::JSON.dump(opts[column]) : opts[column]
59
- end
60
-
61
- { success: true, task_id: Legion::Data::Model::Task.insert(insert), **insert }
62
- rescue StandardError => e
63
- Legion::Logging.error e.message
64
- Legion::Logging.error e.backtrace
65
- raise(e)
66
- end
67
- end
68
- end
69
- end