legionio 0.3.5 → 0.4.0
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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +136 -0
- data/.gitignore +15 -0
- data/.rspec +2 -0
- data/.rubocop.yml +94 -0
- data/CHANGELOG.md +37 -0
- data/Dockerfile +9 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +162 -0
- data/Rakefile +32 -0
- data/bitbucket-pipelines.yml +20 -0
- data/docker_deploy.rb +8 -0
- data/exe/legion +4 -0
- data/exe/legionio +53 -0
- data/exe/lex_gen +5 -0
- data/legionio.gemspec +64 -0
- data/lib/legion.rb +25 -0
- data/lib/legion/cli.rb +56 -0
- data/lib/legion/cli/chain.rb +35 -0
- data/lib/legion/cli/cohort.rb +10 -0
- data/lib/legion/cli/function.rb +41 -0
- data/lib/legion/cli/lex/actor.rb +31 -0
- data/lib/legion/cli/lex/exchange.rb +32 -0
- data/lib/legion/cli/lex/message.rb +32 -0
- data/lib/legion/cli/lex/queue.rb +45 -0
- data/lib/legion/cli/lex/runner.rb +70 -0
- data/lib/legion/cli/lex/templates/actor.erb +6 -0
- data/lib/legion/cli/lex/templates/actor_spec.erb +0 -0
- data/lib/legion/cli/lex/templates/base/bitbucket.yml.erb +69 -0
- data/lib/legion/cli/lex/templates/base/gemfile.erb +3 -0
- data/lib/legion/cli/lex/templates/base/gemspec.erb +26 -0
- data/lib/legion/cli/lex/templates/base/gitignore.erb +11 -0
- data/lib/legion/cli/lex/templates/base/lex.erb +9 -0
- data/lib/legion/cli/lex/templates/base/lex_spec.erb +5 -0
- data/lib/legion/cli/lex/templates/base/lic.erb +21 -0
- data/lib/legion/cli/lex/templates/base/rakefile.erb +6 -0
- data/lib/legion/cli/lex/templates/base/readme.md.erb +2 -0
- data/lib/legion/cli/lex/templates/base/rubocop.yml.erb +15 -0
- data/lib/legion/cli/lex/templates/base/spec_helper.rb.erb +11 -0
- data/lib/legion/cli/lex/templates/base/version.erb +7 -0
- data/lib/legion/cli/lex/templates/exchange.erb +11 -0
- data/lib/legion/cli/lex/templates/exchange_spec.erb +0 -0
- data/lib/legion/cli/lex/templates/message.erb +23 -0
- data/lib/legion/cli/lex/templates/message_spec.erb +0 -0
- data/lib/legion/cli/lex/templates/queue.erb +12 -0
- data/lib/legion/cli/lex/templates/queue_helper.erb +24 -0
- data/lib/legion/cli/lex/templates/queue_spec.erb +11 -0
- data/lib/legion/cli/lex/templates/runner.erb +11 -0
- data/lib/legion/cli/lex/templates/runner_spec.erb +11 -0
- data/lib/legion/cli/relationship.rb +22 -0
- data/lib/legion/cli/task.rb +49 -0
- data/lib/legion/cli/trigger.rb +88 -0
- data/lib/legion/cli/version.rb +5 -0
- data/lib/legion/extensions.rb +219 -0
- data/lib/legion/extensions/actors/base.rb +47 -0
- data/lib/legion/extensions/actors/every.rb +48 -0
- data/lib/legion/extensions/actors/loop.rb +32 -0
- data/lib/legion/extensions/actors/nothing.rb +15 -0
- data/lib/legion/extensions/actors/once.rb +40 -0
- data/lib/legion/extensions/actors/poll.rb +87 -0
- data/lib/legion/extensions/actors/subscription.rb +139 -0
- data/lib/legion/extensions/builders/actors.rb +61 -0
- data/lib/legion/extensions/builders/base.rb +36 -0
- data/lib/legion/extensions/builders/helpers.rb +24 -0
- data/lib/legion/extensions/builders/runners.rb +58 -0
- data/lib/legion/extensions/core.rb +131 -0
- data/lib/legion/extensions/data.rb +58 -0
- data/lib/legion/extensions/data/migrator.rb +28 -0
- data/lib/legion/extensions/data/model.rb +8 -0
- data/lib/legion/extensions/helpers/base.rb +82 -0
- data/lib/legion/extensions/helpers/cache.rb +23 -0
- data/lib/legion/extensions/helpers/core.rb +41 -0
- data/lib/legion/extensions/helpers/data.rb +23 -0
- data/lib/legion/extensions/helpers/lex.rb +48 -0
- data/lib/legion/extensions/helpers/logger.rb +44 -0
- data/lib/legion/extensions/helpers/task.rb +60 -0
- data/lib/legion/extensions/helpers/transport.rb +44 -0
- data/lib/legion/extensions/transport.rb +159 -0
- data/lib/legion/lex.rb +89 -0
- data/lib/legion/process.rb +124 -0
- data/lib/legion/runner.rb +55 -0
- data/lib/legion/runner/log.rb +10 -0
- data/lib/legion/runner/status.rb +69 -0
- data/lib/legion/service.rb +130 -0
- data/lib/legion/supervision.rb +15 -0
- data/lib/legion/version.rb +3 -0
- metadata +239 -38
@@ -0,0 +1,22 @@
|
|
1
|
+
module Legion
|
2
|
+
class Cli
|
3
|
+
class Relationship < Thor
|
4
|
+
desc 'create', 'creates a new relationship'
|
5
|
+
def create(_name, _type)
|
6
|
+
trigger_id = invoke('legion:cli:function:find', [], internal: true, capture: true) # rubocop:disable Lint/UselessAssignment
|
7
|
+
end
|
8
|
+
|
9
|
+
desc 'activate', 'actives a relationship'
|
10
|
+
def active; end
|
11
|
+
|
12
|
+
desc 'deactivate', 'deactivates a relationship'
|
13
|
+
def deactivate; end
|
14
|
+
|
15
|
+
desc 'modify', 'modify an existing relationship'
|
16
|
+
def modify; end
|
17
|
+
|
18
|
+
desc 'delete', 'deletes a relationship'
|
19
|
+
def delete; end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Legion
|
2
|
+
class Cli
|
3
|
+
class Task < Thor
|
4
|
+
package_name 'Legion'
|
5
|
+
|
6
|
+
option :limit, type: :numeric, required: true, default: 10, desc: 'how many tasks to return'
|
7
|
+
desc 'show', 'show'
|
8
|
+
option :status, type: :string, required: false, desc: 'search for specific status'
|
9
|
+
def show
|
10
|
+
Legion::Service.new(cache: false, crypt: false, extensions: false, log_level: 'error')
|
11
|
+
rows = [%w[id relationship function status]]
|
12
|
+
Legion::Data::Model::Task.limit(options[:limit]).order(:id).reverse_each do |row|
|
13
|
+
rows.push([row.values[:id], row.values[:relationship_id], row.values[:function_id], row.values[:status]])
|
14
|
+
end
|
15
|
+
|
16
|
+
print_table rows
|
17
|
+
end
|
18
|
+
|
19
|
+
desc 'test', 'test'
|
20
|
+
def status(id)
|
21
|
+
Legion::Service.new(cache: false, crypt: false, extensions: false, log_level: 'error')
|
22
|
+
say Legion::Data::Model::Task[id].values
|
23
|
+
end
|
24
|
+
|
25
|
+
desc 'logs', 'logs'
|
26
|
+
option :limit, type: :numeric, required: true, default: 10, desc: 'how many tasks to return'
|
27
|
+
def logs(id)
|
28
|
+
Legion::Service.new(cache: false, crypt: false, extensions: false, log_level: 'error')
|
29
|
+
rows = [%w[id node_id created entry]]
|
30
|
+
Legion::Data::Model::TaskLog.where(task_id: id).limit(options[:limit]).each do |row|
|
31
|
+
rows.push([row.values[:id], row.values[:node_id], row.values[:created], row.values[:entry]])
|
32
|
+
end
|
33
|
+
print_table rows
|
34
|
+
end
|
35
|
+
|
36
|
+
desc 'purge', 'purge'
|
37
|
+
def purge
|
38
|
+
Legion::Service.new(cache: false, crypt: false, extensions: false, log_level: 'error')
|
39
|
+
days = ask 'how many days do you want to keep?', default: 7
|
40
|
+
dataset = Legion::Data::Model::Task.where { created < DateTime.now - days.to_i }
|
41
|
+
yes? "This will delete #{dataset.count} tasks, continue?", :red
|
42
|
+
dataset.delete
|
43
|
+
say 'Done!'
|
44
|
+
end
|
45
|
+
|
46
|
+
default_task :show
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Legion
|
2
|
+
class Cli
|
3
|
+
class Trigger < Thor
|
4
|
+
desc 'queue', 'used to send a job directly to a worker via Legion::Transport'
|
5
|
+
option :extension, type: :string, required: false, desc: 'extension short name'
|
6
|
+
option :runner, type: :string, required: false, desc: 'runner short name'
|
7
|
+
option :function, type: :string, required: false, desc: 'function short name'
|
8
|
+
option :delay, type: :numeric, default: 0, desc: 'how long to wait before running the task'
|
9
|
+
def queue(*args) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/MethodLength
|
10
|
+
Legion::Service.new(cache: false, crypt: false, extensions: false, log_level: 'error')
|
11
|
+
include Legion::Extensions::Helpers::Task
|
12
|
+
response = if options['extension'].is_a? String
|
13
|
+
options[:extension]
|
14
|
+
else
|
15
|
+
ask 'trigger extension?', limited_to: Legion::Data::Model::Extension.map(:name)
|
16
|
+
end
|
17
|
+
trigger_extension = Legion::Data::Model::Extension.where(name: response).first
|
18
|
+
runners = Legion::Data::Model::Runner.where(extension_id: trigger_extension.values[:id])
|
19
|
+
if runners.count == 1
|
20
|
+
trigger_runner = runners.first
|
21
|
+
say "Auto selecting #{trigger_runner.values[:name]} since it is the only option for runners"
|
22
|
+
else
|
23
|
+
response = options[:runner].is_a?(String) ? options[:runner] : ask('trigger runner?', limited_to: runners.map(:name))
|
24
|
+
trigger_runner = Legion::Data::Model::Runner.where(name: response).where(extension_id: trigger_extension.values[:id]).first
|
25
|
+
end
|
26
|
+
|
27
|
+
functions = Legion::Data::Model::Function.where(runner_id: trigger_runner.values[:id])
|
28
|
+
|
29
|
+
if functions.count == 1
|
30
|
+
trigger_function = functions.first
|
31
|
+
say "Auto selecting #{trigger_function.values[:name]} since it is the only option for functions"
|
32
|
+
else
|
33
|
+
response = if options[:function].is_a?(String)
|
34
|
+
options[:function]
|
35
|
+
else
|
36
|
+
ask('trigger function?',
|
37
|
+
limited_to: Legion::Data::Model::Function.where(runner_id: trigger_runner.values[:id]).map(:name))
|
38
|
+
end
|
39
|
+
trigger_function = Legion::Data::Model::Function.where(runner_id: trigger_runner.values[:id]).where(name: response).first
|
40
|
+
end
|
41
|
+
say "#{trigger_runner.values[:namespace]}.#{trigger_function.values[:name]} selected as trigger", :green, :italicized
|
42
|
+
payload = {}
|
43
|
+
auto_opts = {}
|
44
|
+
unless args.count.zero?
|
45
|
+
args.each do |arg|
|
46
|
+
test = arg.split(':')
|
47
|
+
auto_opts[test[0].to_sym] = test[1]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
Legion::JSON.load(trigger_function.values[:args]).each do |arg, required|
|
52
|
+
next if %w[args payload opts options].include? arg.to_s
|
53
|
+
|
54
|
+
if auto_opts.key? arg
|
55
|
+
payload[arg.to_sym] = auto_opts[arg]
|
56
|
+
next
|
57
|
+
end
|
58
|
+
response = ask "#{required == 'keyreq' ? '[required]' : '[optional]'} #{arg} value:"
|
59
|
+
if response.empty? && required == 'keyreq'
|
60
|
+
say "Error! #{arg} is required and cannot be empty", :red
|
61
|
+
redo
|
62
|
+
end
|
63
|
+
payload[arg.to_sym] = response unless response.empty?
|
64
|
+
end
|
65
|
+
|
66
|
+
status = options[:delay].zero? ? 'task.queued' : 'task.delayed'
|
67
|
+
task = generate_task_id(function_id: trigger_function.values[:id], status: status, runner_id: trigger_runner.values[:id], args: payload,
|
68
|
+
delay: options[:delay])
|
69
|
+
|
70
|
+
unless options[:delay].zero?
|
71
|
+
say "Task: #{task[:task_id]} is queued and will be run in #{options[:delay]}s"
|
72
|
+
return true
|
73
|
+
end
|
74
|
+
|
75
|
+
routing_key = "#{trigger_extension.values[:exchange]}.#{trigger_runner.values[:queue]}.#{trigger_function.values[:name]}"
|
76
|
+
exchange = Legion::Transport::Messages::Dynamic.new(function: trigger_function.values[:name], function_id: trigger_function.values[:id],
|
77
|
+
routing_key: routing_key, args: payload)
|
78
|
+
exchange.options[:task_id] = task[:task_id]
|
79
|
+
exchange.publish if options[:delay].zero?
|
80
|
+
|
81
|
+
say "Task: #{task[:task_id]} was queued"
|
82
|
+
end
|
83
|
+
remove_command :generate_task_id
|
84
|
+
|
85
|
+
default_task :queue
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,219 @@
|
|
1
|
+
require 'legion/extensions/core'
|
2
|
+
require 'legion/runner'
|
3
|
+
|
4
|
+
module Legion
|
5
|
+
module Extensions
|
6
|
+
class << self
|
7
|
+
def setup
|
8
|
+
hook_extensions
|
9
|
+
end
|
10
|
+
|
11
|
+
def hook_extensions
|
12
|
+
@timer_tasks = []
|
13
|
+
@loop_tasks = []
|
14
|
+
@once_tasks = []
|
15
|
+
@poll_tasks = []
|
16
|
+
@subscription_tasks = []
|
17
|
+
@actors = []
|
18
|
+
|
19
|
+
find_extensions
|
20
|
+
load_extensions
|
21
|
+
end
|
22
|
+
|
23
|
+
def shutdown
|
24
|
+
return nil if @loaded_extensions.nil?
|
25
|
+
|
26
|
+
@subscription_tasks.each do |task|
|
27
|
+
task[:threadpool].shutdown
|
28
|
+
task[:threadpool].kill unless task[:threadpool].wait_for_termination(5)
|
29
|
+
end
|
30
|
+
|
31
|
+
@loop_tasks.each { |task| task[:running_class].cancel if task[:running_class].respond_to?(:cancel) }
|
32
|
+
@once_tasks.each { |task| task[:running_class].cancel if task[:running_class].respond_to?(:cancel) }
|
33
|
+
@timer_tasks.each { |task| task[:running_class].cancel if task[:running_class].respond_to?(:cancel) }
|
34
|
+
@poll_tasks.each { |task| task[:running_class].cancel if task[:running_class].respond_to?(:cancel) }
|
35
|
+
|
36
|
+
Legion::Logging.info 'Successfully shut down all actors'
|
37
|
+
end
|
38
|
+
|
39
|
+
def load_extensions
|
40
|
+
@extensions ||= {}
|
41
|
+
@loaded_extensions ||= []
|
42
|
+
@extensions.each do |extension, values|
|
43
|
+
if values.key(:enabled) && !values[:enabled]
|
44
|
+
Legion::Logging.info "Skipping #{extension} because it's disabled"
|
45
|
+
next
|
46
|
+
end
|
47
|
+
|
48
|
+
if Legion::Settings[:extensions].key?(extension.to_sym) && Legion::Settings[:extensions][extension.to_sym].key?(:enabled) && !Legion::Settings[:extensions][extension.to_sym][:enabled] # rubocop:disable Layout/LineLength
|
49
|
+
next
|
50
|
+
end
|
51
|
+
|
52
|
+
unless load_extension(extension, values)
|
53
|
+
Legion::Logging.warn("#{extension} failed to load")
|
54
|
+
next
|
55
|
+
end
|
56
|
+
@loaded_extensions.push(extension)
|
57
|
+
sleep(0.1)
|
58
|
+
end
|
59
|
+
Legion::Logging.info "#{@extensions.count} extensions loaded with subscription:#{@subscription_tasks.count},every:#{@timer_tasks.count},poll:#{@poll_tasks.count},once:#{@once_tasks.count},loop:#{@loop_tasks.count}"
|
60
|
+
end
|
61
|
+
|
62
|
+
def load_extension(extension, values)
|
63
|
+
return unless gem_load(values[:gem_name], extension)
|
64
|
+
|
65
|
+
extension = Kernel.const_get(values[:extension_class])
|
66
|
+
if extension.data_required? && Legion::Settings[:data][:connected] == false
|
67
|
+
Legion::Logging.warn "#{values[:extension_name]} requires Legion::Data but isn't enabled, skipping"
|
68
|
+
return false
|
69
|
+
end
|
70
|
+
|
71
|
+
if extension.cache_required? && Legion::Settings[:cache][:connected] == false
|
72
|
+
Legion::Logging.warn "#{values[:extension_name]} requires Legion::Cache but isn't enabled, skipping"
|
73
|
+
return false
|
74
|
+
end
|
75
|
+
|
76
|
+
if extension.vault_required? && Legion::Settings[:crypt][:vault][:connected] == false
|
77
|
+
Legion::Logging.warn "#{values[:extension_name]} requires Legion::Crypt::Vault but isn't enabled, skipping"
|
78
|
+
return false
|
79
|
+
end
|
80
|
+
|
81
|
+
has_logger = extension.respond_to?(:log)
|
82
|
+
extension.autobuild
|
83
|
+
|
84
|
+
require 'legion/transport/messages/lex_register'
|
85
|
+
Legion::Transport::Messages::LexRegister.new(function: 'save', opts: extension.runners).publish
|
86
|
+
|
87
|
+
if extension.respond_to?(:meta_actors) && extension.meta_actors.is_a?(Array)
|
88
|
+
extension.meta_actors.each do |_key, actor|
|
89
|
+
extension.log.debug("hooking meta actor: #{actor}") if has_logger
|
90
|
+
hook_actor(**actor)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
extension.actors.each do |_key, actor|
|
95
|
+
extension.log.debug("hooking literal actor: #{actor}") if has_logger
|
96
|
+
hook_actor(**actor)
|
97
|
+
end
|
98
|
+
extension.log.info "Loaded v#{extension::VERSION}"
|
99
|
+
rescue StandardError => e
|
100
|
+
Legion::Logging.error e.message
|
101
|
+
Legion::Logging.error e.backtrace
|
102
|
+
false
|
103
|
+
end
|
104
|
+
|
105
|
+
def hook_actor(extension:, extension_name:, actor_class:, size: 1, **opts)
|
106
|
+
size = if Legion::Settings[:extensions].key?(extension_name.to_sym) && Legion::Settings[:extensions][extension_name.to_sym].key?(:workers)
|
107
|
+
Legion::Settings[:extensions][extension_name.to_sym][:workers]
|
108
|
+
elsif size.is_a? Integer
|
109
|
+
size
|
110
|
+
else
|
111
|
+
1
|
112
|
+
end
|
113
|
+
|
114
|
+
extension_hash = {
|
115
|
+
extension: extension,
|
116
|
+
extension_name: extension_name,
|
117
|
+
actor_class: actor_class,
|
118
|
+
size: size,
|
119
|
+
fallback_policy: :abort,
|
120
|
+
**opts
|
121
|
+
}
|
122
|
+
extension_hash[:running_class] = if actor_class.ancestors.include? Legion::Extensions::Actors::Subscription
|
123
|
+
actor_class
|
124
|
+
else
|
125
|
+
actor_class.new
|
126
|
+
end
|
127
|
+
|
128
|
+
return if extension_hash[:running_class].respond_to?(:enabled?) && !extension_hash[:running_class].enabled?
|
129
|
+
|
130
|
+
if actor_class.ancestors.include? Legion::Extensions::Actors::Every
|
131
|
+
@timer_tasks.push(extension_hash)
|
132
|
+
elsif actor_class.ancestors.include? Legion::Extensions::Actors::Once
|
133
|
+
@once_tasks.push(extension_hash)
|
134
|
+
elsif actor_class.ancestors.include? Legion::Extensions::Actors::Loop
|
135
|
+
@loop_tasks.push(extension_hash)
|
136
|
+
elsif actor_class.ancestors.include? Legion::Extensions::Actors::Poll
|
137
|
+
@poll_tasks.push(extension_hash)
|
138
|
+
elsif actor_class.ancestors.include? Legion::Extensions::Actors::Subscription
|
139
|
+
extension_hash[:threadpool] = Concurrent::FixedThreadPool.new(size)
|
140
|
+
size.times do
|
141
|
+
extension_hash[:threadpool].post do
|
142
|
+
klass = actor_class.new
|
143
|
+
if klass.respond_to?(:async)
|
144
|
+
klass.async.subscribe
|
145
|
+
else
|
146
|
+
klass.subscribe
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
@subscription_tasks.push(extension_hash)
|
151
|
+
else
|
152
|
+
Legion::Logging.fatal 'did not match any actor classes'
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def gem_load(gem_name, name)
|
157
|
+
require "#{Gem::Specification.find_by_name(gem_name).gem_dir}/lib/legion/extensions/#{name}"
|
158
|
+
true
|
159
|
+
rescue LoadError => e
|
160
|
+
Legion::Logging.error e.message
|
161
|
+
Legion::Logging.error e.backtrace
|
162
|
+
Legion::Logging.error "gem_path: #{gem_path}" unless gem_path.nil?
|
163
|
+
false
|
164
|
+
end
|
165
|
+
|
166
|
+
def find_extensions
|
167
|
+
@extensions ||= {}
|
168
|
+
Gem::Specification.all_names.each do |gem|
|
169
|
+
next unless gem[0..3] == 'lex-'
|
170
|
+
|
171
|
+
lex = gem.split('-')
|
172
|
+
@extensions[lex[1]] = { full_gem_name: gem,
|
173
|
+
gem_name: "lex-#{lex[1]}",
|
174
|
+
extension_name: lex[1],
|
175
|
+
version: lex[2],
|
176
|
+
extension_class: "Legion::Extensions::#{lex[1].split('_').collect(&:capitalize).join}" }
|
177
|
+
end
|
178
|
+
|
179
|
+
enabled = 0
|
180
|
+
requested = 0
|
181
|
+
|
182
|
+
Legion::Settings[:extensions].each do |extension, values|
|
183
|
+
next if @extensions.key? extension.to_s
|
184
|
+
next if values[:enabled] == false
|
185
|
+
|
186
|
+
requested += 1
|
187
|
+
next if values[:auto_install] == false
|
188
|
+
next if ENV['_'].include? 'bundle'
|
189
|
+
|
190
|
+
Legion::Logging.warn "#{extension} is missing, attempting to install automatically.."
|
191
|
+
install = Gem.install("lex-#{extension}", values[:version])
|
192
|
+
Legion::Logging.debug(install)
|
193
|
+
lex = Gem::Specification.find_by_name("lex-#{extension}")
|
194
|
+
|
195
|
+
@extensions[extension.to_s] = {
|
196
|
+
full_gem_name: "lex-#{extension}-#{lex.version}",
|
197
|
+
gem_name: "lex-#{extension}",
|
198
|
+
extension_name: extension.to_s,
|
199
|
+
version: lex.version,
|
200
|
+
extension_class: "Legion::Extensions::#{extension.to_s.split('_').collect(&:capitalize).join}"
|
201
|
+
}
|
202
|
+
|
203
|
+
enabled += 1
|
204
|
+
|
205
|
+
rescue StandardError, Gem::MissingSpecError => e
|
206
|
+
Legion::Logging.error "Failed to auto install #{extension}, e: #{e.message}"
|
207
|
+
end
|
208
|
+
return true if requested == enabled
|
209
|
+
|
210
|
+
Legion::Logging.warn "A total of #{requested - enabled} where skipped"
|
211
|
+
if ENV['_'].include?('bundle')
|
212
|
+
Legion::Logging.warn 'Please add them to your Gemfile since you are using bundler'
|
213
|
+
else
|
214
|
+
Legion::Logging.warn 'You must have auto_install_missing_lex set to true to auto install missing extensions'
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Legion
|
2
|
+
module Extensions
|
3
|
+
module Actors
|
4
|
+
module Base
|
5
|
+
include Legion::Extensions::Helpers::Lex
|
6
|
+
|
7
|
+
def runner
|
8
|
+
Legion::Runner.run(runner_class: runner_class, function: function, check_subtask: check_subtask?, generate_task: generate_task?)
|
9
|
+
rescue StandardError => e
|
10
|
+
Legion::Logging.error e.message
|
11
|
+
Legion::Logging.error e.backtrace
|
12
|
+
end
|
13
|
+
|
14
|
+
def manual
|
15
|
+
runner_class.send(runner_function, **args)
|
16
|
+
rescue StandardError => e
|
17
|
+
Legion::Logging.error e.message
|
18
|
+
Legion::Logging.error e.backtrace
|
19
|
+
end
|
20
|
+
|
21
|
+
def function
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def use_runner?
|
26
|
+
true
|
27
|
+
end
|
28
|
+
|
29
|
+
def args
|
30
|
+
{}
|
31
|
+
end
|
32
|
+
|
33
|
+
def check_subtask?
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def generate_task?
|
38
|
+
false
|
39
|
+
end
|
40
|
+
|
41
|
+
def enabled?
|
42
|
+
true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module Legion
|
4
|
+
module Extensions
|
5
|
+
module Actors
|
6
|
+
class Every
|
7
|
+
include Legion::Extensions::Actors::Base
|
8
|
+
|
9
|
+
def initialize(**_opts)
|
10
|
+
@timer = Concurrent::TimerTask.new(execution_interval: time, timeout_interval: timeout, run_now: run_now?) do
|
11
|
+
use_runner? ? runner : manual
|
12
|
+
end
|
13
|
+
|
14
|
+
@timer.execute
|
15
|
+
rescue StandardError => e
|
16
|
+
Legion::Logging.error e.message
|
17
|
+
Legion::Logging.error e.backtrace
|
18
|
+
end
|
19
|
+
|
20
|
+
def time
|
21
|
+
1
|
22
|
+
end
|
23
|
+
|
24
|
+
def timeout
|
25
|
+
5
|
26
|
+
end
|
27
|
+
|
28
|
+
def run_now?
|
29
|
+
false
|
30
|
+
end
|
31
|
+
|
32
|
+
def action(**_opts)
|
33
|
+
Legion::Logging.warn 'An extension is using the default block from Legion::Extensions::Runners::Every'
|
34
|
+
end
|
35
|
+
|
36
|
+
def cancel
|
37
|
+
Legion::Logging.debug 'Cancelling Legion Timer'
|
38
|
+
return true unless @timer.respond_to?(:shutdown)
|
39
|
+
|
40
|
+
@timer.shutdown
|
41
|
+
rescue StandardError => e
|
42
|
+
Legion::Logging.error e.message
|
43
|
+
Legion::Logging.error e.backtrace
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|