legionio 0.3.4 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- 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 +47 -0
- data/Dockerfile +9 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +161 -0
- data/Rakefile +32 -0
- data/bitbucket-pipelines.yml +19 -0
- data/docker_deploy.rb +10 -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/defaults.rb +28 -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 +244 -39
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'legion/extensions/<%= config[:lex] %>/runners/<%= config[:name] %>'
|
3
|
+
|
4
|
+
RSpec.describe Legion::Extensions::<%= config[:lex].split('_').collect(&:capitalize).join %>::Runners::<%= config[:name].capitalize %> do
|
5
|
+
it { should be_a Module }
|
6
|
+
Legion::Extensions::<%= config[:lex].capitalize %>::Runners::<%= config[:name].split('_').collect(&:capitalize).join %>.extend Legion::Extensions::<%= config[:lex].split('_').collect(&:capitalize).join %>::Runners::<%= config[:name].split('_').collect(&:capitalize).join %>
|
7
|
+
|
8
|
+
describe 'Functions should work with arguments' do
|
9
|
+
let(:test_class) { Class.new { extend Legion::Extensions::<%= config[:lex].split('_').collect(&:capitalize).join %>::Runners::<%= config[:name].split('_').collect(&:capitalize).join %> } }
|
10
|
+
end
|
11
|
+
end
|
@@ -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.key?('_') && 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
|