legionio 0.3.2 → 0.3.3

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 (90) hide show
  1. checksums.yaml +4 -4
  2. metadata +4 -94
  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 -49
  11. data/Rakefile +0 -38
  12. data/bin/console +0 -16
  13. data/bin/legion +0 -49
  14. data/bin/setup +0 -8
  15. data/bin/test +0 -32
  16. data/bitbucket-pipelines.yml +0 -55
  17. data/docs/Makefile +0 -20
  18. data/docs/_build/doctrees/environment.pickle +0 -0
  19. data/docs/_build/doctrees/index.doctree +0 -0
  20. data/docs/_build/doctrees/overview.doctree +0 -0
  21. data/docs/_build/html/.buildinfo +0 -4
  22. data/docs/_build/html/_sources/index.rst.txt +0 -28
  23. data/docs/_build/html/_sources/overview.rst.txt +0 -0
  24. data/docs/_build/html/_static/alabaster.css +0 -701
  25. data/docs/_build/html/_static/basic.css +0 -855
  26. data/docs/_build/html/_static/custom.css +0 -1
  27. data/docs/_build/html/_static/doctools.js +0 -315
  28. data/docs/_build/html/_static/documentation_options.js +0 -12
  29. data/docs/_build/html/_static/file.png +0 -0
  30. data/docs/_build/html/_static/jquery-3.5.1.js +0 -10872
  31. data/docs/_build/html/_static/jquery.js +0 -2
  32. data/docs/_build/html/_static/language_data.js +0 -297
  33. data/docs/_build/html/_static/minus.png +0 -0
  34. data/docs/_build/html/_static/plus.png +0 -0
  35. data/docs/_build/html/_static/pygments.css +0 -82
  36. data/docs/_build/html/_static/searchtools.js +0 -514
  37. data/docs/_build/html/_static/underscore-1.3.1.js +0 -999
  38. data/docs/_build/html/_static/underscore.js +0 -31
  39. data/docs/_build/html/genindex.html +0 -101
  40. data/docs/_build/html/index.html +0 -117
  41. data/docs/_build/html/objects.inv +0 -6
  42. data/docs/_build/html/overview.html +0 -98
  43. data/docs/_build/html/search.html +0 -110
  44. data/docs/_build/html/searchindex.js +0 -1
  45. data/docs/conf.py +0 -54
  46. data/docs/index.rst +0 -28
  47. data/docs/make.bat +0 -35
  48. data/exe/legion +0 -52
  49. data/legion.gemspec +0 -59
  50. data/lib/legion.rb +0 -21
  51. data/lib/legion/exceptions/handled_task.rb +0 -6
  52. data/lib/legion/exceptions/invalidjson.rb +0 -5
  53. data/lib/legion/exceptions/missingargument.rb +0 -6
  54. data/lib/legion/exceptions/wrongtype.rb +0 -10
  55. data/lib/legion/exceptions/wrongtypes/array.rb +0 -8
  56. data/lib/legion/exceptions/wrongtypes/hash.rb +0 -8
  57. data/lib/legion/exceptions/wrongtypes/integer.rb +0 -8
  58. data/lib/legion/exceptions/wrongtypes/string.rb +0 -8
  59. data/lib/legion/extensions.rb +0 -185
  60. data/lib/legion/extensions/actors/base.rb +0 -49
  61. data/lib/legion/extensions/actors/every.rb +0 -48
  62. data/lib/legion/extensions/actors/loop.rb +0 -32
  63. data/lib/legion/extensions/actors/nothing.rb +0 -15
  64. data/lib/legion/extensions/actors/once.rb +0 -40
  65. data/lib/legion/extensions/actors/poll.rb +0 -88
  66. data/lib/legion/extensions/actors/subscription.rb +0 -138
  67. data/lib/legion/extensions/builders/actors.rb +0 -61
  68. data/lib/legion/extensions/builders/base.rb +0 -36
  69. data/lib/legion/extensions/builders/helpers.rb +0 -24
  70. data/lib/legion/extensions/builders/runners.rb +0 -58
  71. data/lib/legion/extensions/core.rb +0 -126
  72. data/lib/legion/extensions/data.rb +0 -58
  73. data/lib/legion/extensions/data/migrator.rb +0 -28
  74. data/lib/legion/extensions/data/model.rb +0 -8
  75. data/lib/legion/extensions/helpers/base.rb +0 -82
  76. data/lib/legion/extensions/helpers/cache.rb +0 -23
  77. data/lib/legion/extensions/helpers/core.rb +0 -41
  78. data/lib/legion/extensions/helpers/data.rb +0 -23
  79. data/lib/legion/extensions/helpers/lex.rb +0 -48
  80. data/lib/legion/extensions/helpers/logger.rb +0 -47
  81. data/lib/legion/extensions/helpers/task.rb +0 -60
  82. data/lib/legion/extensions/helpers/transport.rb +0 -44
  83. data/lib/legion/extensions/transport.rb +0 -159
  84. data/lib/legion/process.rb +0 -124
  85. data/lib/legion/runner.rb +0 -55
  86. data/lib/legion/runner/log.rb +0 -10
  87. data/lib/legion/runner/status.rb +0 -69
  88. data/lib/legion/service.rb +0 -99
  89. data/lib/legion/supervision.rb +0 -15
  90. data/lib/legion/version.rb +0 -3
@@ -1,41 +0,0 @@
1
- require_relative 'base'
2
- module Legion
3
- module Extensions
4
- module Helpers
5
- module Core
6
- include Legion::Extensions::Helpers::Base
7
-
8
- def settings
9
- if Legion::Settings[:extensions].key?(lex_filename.to_sym)
10
- Legion::Settings[:extensions][lex_filename.to_sym]
11
- else
12
- { logger: { level: 'info', extended: false, internal: false } }
13
- end
14
- end
15
-
16
- # looks local, then in crypt, then settings, then cache, then env
17
- def find_setting(name, **opts)
18
- log.debug ".find_setting(#{name}) called"
19
- return opts[name.to_sym] if opts.key? name.to_sym
20
-
21
- string_name = "#{lex_name}_#{name.to_s.downcase}"
22
- if Legion::Settings[:crypt][:vault][:connected] && Legion::Crypt.exist?(lex_name)
23
- log.debug "looking for #{string_name} in Legion::Crypt"
24
- crypt_result = Legion::Crypt.get(lex_name)
25
- return crypt_result[name.to_sym] if crypt_result.is_a?(Hash) && crypt_result.key?(name.to_sym)
26
- end
27
- return settings[name.to_sym] if settings.key? name.to_sym
28
-
29
- if Legion::Settings[:cache][:connected]
30
- log.debug "looking for #{string_name} in Legion::Cache"
31
- cache_result = Legion::Cache.get(string_name)
32
- return cache_result unless cache_result.nil?
33
- end
34
-
35
- ENV[string_name] if ENV.key? string_name
36
- nil
37
- end
38
- end
39
- end
40
- end
41
- end
@@ -1,23 +0,0 @@
1
- require 'legion/extensions/helpers/base'
2
-
3
- module Legion
4
- module Extensions
5
- module Helpers
6
- module Data
7
- include Legion::Extensions::Helpers::Base
8
-
9
- def data_path
10
- @data_path ||= "#{full_path}/data"
11
- end
12
-
13
- def data_class
14
- @data_class ||= lex_class::Data
15
- end
16
-
17
- def models_class
18
- @models_class ||= data_class::Model
19
- end
20
- end
21
- end
22
- end
23
- end
@@ -1,48 +0,0 @@
1
- module Legion
2
- module Extensions
3
- module Helpers
4
- module Lex
5
- include Legion::Extensions::Helpers::Core
6
- include Legion::Extensions::Helpers::Logger
7
-
8
- def function_example(function, example)
9
- function_set(function, :example, example)
10
- end
11
-
12
- def function_options(function, options)
13
- function_set(function, :options, options)
14
- end
15
-
16
- def function_desc(function, desc)
17
- function_set(function, :desc, desc)
18
- end
19
-
20
- def function_set(function, key, value)
21
- unless respond_to? function
22
- log.debug "function_#{key} called but function doesn't exist, f: #{function}"
23
- return nil
24
- end
25
- settings[:functions] = {} if settings[:functions].nil?
26
- settings[:functions][function] = {} if settings[:functions][function].nil?
27
- settings[:functions][function][key] = value
28
- end
29
-
30
- def runner_desc(desc)
31
- settings[:runners] = {} if settings[:runners].nil?
32
- settings[:runners][actor_name.to_sym] = {} if settings[:runners][actor_name.to_sym].nil?
33
- settings[:runners][actor_name.to_sym][:desc] = desc
34
- end
35
-
36
- def self.included(base)
37
- base.send :extend, Legion::Extensions::Helpers::Core if base.instance_of?(Class)
38
- base.send :extend, Legion::Extensions::Helpers::Logger if base.instance_of?(Class)
39
- base.extend base if base.instance_of?(Module)
40
- end
41
-
42
- def default_settings
43
- { logger: { level: 'info' }, workers: 1, runners: {}, functions: {} }
44
- end
45
- end
46
- end
47
- end
48
- end
@@ -1,47 +0,0 @@
1
- module Legion
2
- module Extensions
3
- module Helpers
4
- module Logger
5
- def log # rubocop:disable Metrics/AbcSize
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][:level] if settings[:logger].key? :level
12
- logger_hash[:level] = settings[:logger][:log_file] if settings[:logger].key? :log_file
13
- logger_hash[:level] = 'info' unless settings[:logger].key? :log_file
14
- logger_hash[:trace] = settings[:logger][:trace] if settings[:logger].key? :trace
15
- logger_hash[:extended] = settings[:logger][:extended] if settings[:logger].key? :extended
16
- elsif respond_to?(:settings)
17
- Legion::Logging.warn Legion::Settings[:extensions][lex_filename.to_sym]
18
- Legion::Logging.warn "#{lex_name} has settings but no :logger key"
19
- else
20
- Legion::Logging.warn 'no settings'
21
- end
22
- @log = Legion::Logging::Logger.new(**logger_hash)
23
- end
24
-
25
- def handle_exception(exception, task_id: nil, **opts)
26
- log.error exception.message + " for task_id: #{task_id} but was logged "
27
- log.error exception.backtrace[0..10]
28
- log.error opts
29
-
30
- unless task_id.nil?
31
- Legion::Transport::Messages::TaskLog.new(
32
- task_id: task_id,
33
- runner_class: to_s,
34
- entry: {
35
- exception: true,
36
- message: exception.message,
37
- **opts
38
- }
39
- ).publish
40
- end
41
-
42
- raise Legion::Exception::HandledTask
43
- end
44
- end
45
- end
46
- end
47
- end
@@ -1,60 +0,0 @@
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.warn("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
@@ -1,44 +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
- @default_exchange
40
- end
41
- end
42
- end
43
- end
44
- end
@@ -1,159 +0,0 @@
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
@@ -1,124 +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
- @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