legionio 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
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