legionio 0.3.1 → 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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +27 -10
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +7 -2
  5. data/CHANGELOG.md +21 -0
  6. data/Dockerfile +9 -0
  7. data/Gemfile +0 -11
  8. data/README.md +158 -42
  9. data/Rakefile +0 -6
  10. data/bitbucket-pipelines.yml +17 -52
  11. data/docker_deploy.rb +8 -0
  12. data/exe/legion +3 -49
  13. data/{bin/legion → exe/legionio} +5 -42
  14. data/exe/lex_gen +5 -0
  15. data/{legion.gemspec → legionio.gemspec} +25 -20
  16. data/lib/legion.rb +4 -0
  17. data/lib/legion/cli.rb +56 -0
  18. data/lib/legion/cli/chain.rb +35 -0
  19. data/lib/legion/cli/cohort.rb +10 -0
  20. data/lib/legion/cli/function.rb +41 -0
  21. data/lib/legion/cli/lex/actor.rb +31 -0
  22. data/lib/legion/cli/lex/exchange.rb +32 -0
  23. data/lib/legion/cli/lex/message.rb +32 -0
  24. data/lib/legion/cli/lex/queue.rb +45 -0
  25. data/lib/legion/cli/lex/runner.rb +70 -0
  26. data/lib/legion/cli/lex/templates/actor.erb +6 -0
  27. data/lib/legion/cli/lex/templates/actor_spec.erb +0 -0
  28. data/lib/legion/cli/lex/templates/base/bitbucket.yml.erb +69 -0
  29. data/lib/legion/cli/lex/templates/base/gemfile.erb +3 -0
  30. data/lib/legion/cli/lex/templates/base/gemspec.erb +26 -0
  31. data/lib/legion/cli/lex/templates/base/gitignore.erb +11 -0
  32. data/lib/legion/cli/lex/templates/base/lex.erb +9 -0
  33. data/lib/legion/cli/lex/templates/base/lex_spec.erb +5 -0
  34. data/lib/legion/cli/lex/templates/base/lic.erb +21 -0
  35. data/lib/legion/cli/lex/templates/base/rakefile.erb +6 -0
  36. data/lib/legion/cli/lex/templates/base/readme.md.erb +2 -0
  37. data/lib/legion/cli/lex/templates/base/rubocop.yml.erb +15 -0
  38. data/lib/legion/cli/lex/templates/base/spec_helper.rb.erb +11 -0
  39. data/lib/legion/cli/lex/templates/base/version.erb +7 -0
  40. data/lib/legion/cli/lex/templates/exchange.erb +11 -0
  41. data/lib/legion/cli/lex/templates/exchange_spec.erb +0 -0
  42. data/lib/legion/cli/lex/templates/message.erb +23 -0
  43. data/lib/legion/cli/lex/templates/message_spec.erb +0 -0
  44. data/lib/legion/cli/lex/templates/queue.erb +12 -0
  45. data/lib/legion/cli/lex/templates/queue_helper.erb +24 -0
  46. data/lib/legion/cli/lex/templates/queue_spec.erb +11 -0
  47. data/lib/legion/cli/lex/templates/runner.erb +11 -0
  48. data/lib/legion/cli/lex/templates/runner_spec.erb +11 -0
  49. data/lib/legion/cli/relationship.rb +22 -0
  50. data/lib/legion/cli/task.rb +49 -0
  51. data/lib/legion/cli/trigger.rb +88 -0
  52. data/lib/legion/cli/version.rb +5 -0
  53. data/lib/legion/extensions.rb +57 -62
  54. data/lib/legion/extensions/actors/base.rb +0 -2
  55. data/lib/legion/extensions/actors/poll.rb +0 -1
  56. data/lib/legion/extensions/actors/subscription.rb +1 -0
  57. data/lib/legion/extensions/builders/runners.rb +5 -0
  58. data/lib/legion/extensions/core.rb +9 -4
  59. data/lib/legion/extensions/helpers/base.rb +3 -3
  60. data/lib/legion/extensions/helpers/lex.rb +29 -1
  61. data/lib/legion/extensions/helpers/logger.rb +3 -6
  62. data/lib/legion/extensions/helpers/task.rb +1 -1
  63. data/lib/legion/extensions/transport.rb +9 -7
  64. data/lib/legion/lex.rb +89 -0
  65. data/lib/legion/service.rb +55 -4
  66. data/lib/legion/version.rb +1 -1
  67. metadata +196 -51
  68. data/bin/console +0 -16
  69. data/bin/setup +0 -8
  70. data/bin/test +0 -32
  71. data/lib/legion/exceptions/handled_task.rb +0 -6
  72. data/lib/legion/exceptions/invalidjson.rb +0 -5
  73. data/lib/legion/exceptions/missingargument.rb +0 -6
  74. data/lib/legion/exceptions/wrongtype.rb +0 -10
  75. data/lib/legion/exceptions/wrongtypes/array.rb +0 -8
  76. data/lib/legion/exceptions/wrongtypes/hash.rb +0 -8
  77. data/lib/legion/exceptions/wrongtypes/integer.rb +0 -8
  78. data/lib/legion/exceptions/wrongtypes/string.rb +0 -8
  79. data/settings/client.json +0 -25
@@ -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,5 @@
1
+ module Legion
2
+ class Cli
3
+ VERSION = '0.2.0'.freeze
4
+ end
5
+ end
@@ -54,6 +54,7 @@ module Legion
54
54
  next
55
55
  end
56
56
  @loaded_extensions.push(extension)
57
+ sleep(0.1)
57
58
  end
58
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}"
59
60
  end
@@ -62,6 +63,21 @@ module Legion
62
63
  return unless gem_load(values[:gem_name], extension)
63
64
 
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
+
65
81
  has_logger = extension.respond_to?(:log)
66
82
  extension.autobuild
67
83
 
@@ -109,6 +125,8 @@ module Legion
109
125
  actor_class.new
110
126
  end
111
127
 
128
+ return if extension_hash[:running_class].respond_to?(:enabled?) && !extension_hash[:running_class].enabled?
129
+
112
130
  if actor_class.ancestors.include? Legion::Extensions::Actors::Every
113
131
  @timer_tasks.push(extension_hash)
114
132
  elsif actor_class.ancestors.include? Legion::Extensions::Actors::Once
@@ -136,8 +154,7 @@ module Legion
136
154
  end
137
155
 
138
156
  def gem_load(gem_name, name)
139
- gem_path = "#{Gem::Specification.find_by_name(gem_name).gem_dir}/lib/legion/extensions/#{name}"
140
- require gem_path
157
+ require "#{Gem::Specification.find_by_name(gem_name).gem_dir}/lib/legion/extensions/#{name}"
141
158
  true
142
159
  rescue LoadError => e
143
160
  Legion::Logging.error e.message
@@ -148,62 +165,6 @@ module Legion
148
165
 
149
166
  def find_extensions
150
167
  @extensions ||= {}
151
- # puts Gem.install('lex-esphome')
152
- # puts Gem::Installer.new('lex-esphome')
153
- # test = Gem::Installer.new('lex-esphome')
154
- # puts test.install
155
- # puts Gem::Dependency.new('lex-esphome')
156
- # $LOAD_PATH << "#{ENV['GEM_HOME']}/gems/lex-esphome-0.1.0/lib"
157
- # require 'legion/extensions/esphome'
158
- # $LOAD_PATH << "#{ENV['GEM_HOME']}/gems/lex-esphome-0.1.0/lib"
159
- # ENV['MY_RUBY_HOME'] #/Users/miverso2/.rvm/rubies/ruby-2.7.0
160
- # ENV['GEM_HOME'] # /Users/miverso2/.rvm/gems/ruby-2.7.0
161
- # require 'rubygems/dependency_installer.rb'
162
- # puts Gem::DependencyInstaller.new.install('lex-esphome')
163
- # puts Gem::Installer.new('lex-esphome').install
164
- # puts Gem::Installer.new('lex-esphome').ensure_loadable_spec
165
- # puts Gem.search('lex-esphome')
166
- # Gem.clear_paths
167
- # require 'legion/extensions/esphome'
168
-
169
- # puts Gem.use_gemdeps
170
- # pp Gem.gemdeps
171
- # puts 'gems things'
172
- # puts Gem.loaded_specs.key? 'lex-esphome'
173
- # pp Gem.loaded_specs.keys
174
- #
175
- # require 'rubygems'
176
- # require 'rubygems/command.rb'
177
- # require 'rubygems/dependency_installer.rb'
178
- #
179
- # Gem::Command.build_args = ARGV
180
- # inst = Gem::DependencyInstaller.new
181
- # puts inst.installed_gems
182
- # puts inst.install 'lex-esphome', install_as_default: true
183
- # puts inst.installed_gems
184
- # puts '....'
185
- # test = Gem::DependencyList.new
186
- # test.add(inst)
187
- # pp test.find_name('lex-esphome')
188
- # pp test.find_name('lex-logger')
189
- # pp test.specs
190
- # pp Gem::DependencyList.from_specs
191
- # pp Gem::DependencyList.from_specs.key? 'lex-logg'
192
- # pp inst
193
- #
194
- # pp Gem.new.all_specs
195
- # load 'legion/extensions/esphome.rb'
196
- # puts Gem.register_default_spec()
197
- # :use_gemdeps,
198
- # :detect_gemdeps,
199
- # :source_date_epoch,
200
- # :gemdeps,
201
- # :register_default_spec,
202
- # :find_unresolved_default_spec,
203
- # :clear_default_specs,
204
- # :loaded_specs,
205
- # :default_path,
206
-
207
168
  Gem::Specification.all_names.each do |gem|
208
169
  next unless gem[0..3] == 'lex-'
209
170
 
@@ -212,12 +173,46 @@ module Legion
212
173
  gem_name: "lex-#{lex[1]}",
213
174
  extension_name: lex[1],
214
175
  version: lex[2],
215
- extension_class: "Legion::Extensions::#{lex[1].capitalize}" }
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}"
216
207
  end
208
+ return true if requested == enabled
217
209
 
218
- # Legion::Settings[:extensions].each do |extension|
219
- # puts extension unless @extensions.key? extension
220
- # end
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
221
216
  end
222
217
  end
223
218
  end
@@ -1,5 +1,3 @@
1
- require 'hashdiff'
2
-
3
1
  module Legion
4
2
  module Extensions
5
3
  module Actors
@@ -1,5 +1,4 @@
1
1
  require_relative 'base'
2
- require 'hashdiff'
3
2
  require 'time'
4
3
 
5
4
  module Legion
@@ -12,6 +12,7 @@ module Legion
12
12
  def initialize(**_options)
13
13
  super()
14
14
  @queue = queue.new
15
+ @queue.channel.prefetch(prefetch) if defined? prefetch
15
16
  rescue StandardError => e
16
17
  log.fatal e.message
17
18
  log.fatal e.backtrace
@@ -20,6 +20,7 @@ module Legion
20
20
  runner_name = file.split('/').last.sub('.rb', '')
21
21
  runner_class = "#{lex_class}::Runners::#{runner_name.split('_').collect(&:capitalize).join}"
22
22
  loaded_runner = Kernel.const_get(runner_class)
23
+
23
24
  @runners[runner_name.to_sym] = {
24
25
  extension: lex_class.to_s.downcase,
25
26
  extension_name: extension_name,
@@ -30,6 +31,10 @@ module Legion
30
31
  class_methods: {}
31
32
  }
32
33
 
34
+ if settings.key?(:runners) && settings[:runners].key?(runner_name.to_sym)
35
+ @runners[runner_name.to_sym][:desc] = settings[:runners][runner_name.to_sym][:desc]
36
+ end
37
+
33
38
  loaded_runner.public_instance_methods(false).each do |runner_method|
34
39
  @runners[runner_name.to_sym][:class_methods][runner_method] = {
35
40
  args: loaded_runner.instance_method(runner_method).parameters
@@ -39,7 +39,7 @@ module Legion
39
39
  @messages = {}
40
40
  build_settings
41
41
  build_transport
42
- build_data
42
+ build_data if Legion::Settings[:data][:connected] && data_required?
43
43
  build_helpers
44
44
  build_runners
45
45
  build_actors
@@ -61,9 +61,13 @@ module Legion
61
61
  false
62
62
  end
63
63
 
64
+ def vault_required?
65
+ false
66
+ end
67
+
64
68
  def build_data
65
69
  auto_generate_data
66
- extension_class::Data.build
70
+ lex_class::Data.build
67
71
  end
68
72
 
69
73
  def build_transport
@@ -117,9 +121,10 @@ module Legion
117
121
  def auto_generate_data
118
122
  require 'legion/extensions/data'
119
123
  log.debug 'running meta magic to generate a data base class'
120
- return if Kernel.const_defined? "#{lex_class}::Data"
121
-
122
124
  Kernel.const_get(lex_class.to_s).const_set('Data', Module.new { extend Legion::Extensions::Data })
125
+ rescue StandardError => e
126
+ log.error e.message
127
+ log.error e.backtrace
123
128
  end
124
129
  end
125
130
  end
@@ -8,7 +8,7 @@ module Legion
8
8
  alias extension_class lex_class
9
9
 
10
10
  def lex_name
11
- @lex_name ||= calling_class_array[2].gsub(/(?<!^)[A-Z]/) { "_#{$&}" }.downcase
11
+ @lex_name ||= calling_class_array[2].gsub(/(?<!^)[A-Z]/) { "_#{Regexp.last_match(0)}" }.downcase
12
12
  end
13
13
  alias extension_name lex_name
14
14
  alias lex_filename lex_name
@@ -30,7 +30,7 @@ module Legion
30
30
  end
31
31
 
32
32
  def actor_name
33
- @actor_name ||= calling_class_array.last.gsub(/(?<!^)[A-Z]/) { "_#{$&}" }.downcase
33
+ @actor_name ||= calling_class_array.last.gsub(/(?<!^)[A-Z]/) { "_#{Regexp.last_match(0)}" }.downcase
34
34
  end
35
35
 
36
36
  def actor_const
@@ -42,7 +42,7 @@ module Legion
42
42
  end
43
43
 
44
44
  def runner_name
45
- @runner_name ||= runner_class.to_s.split('::').last.gsub(/(?<!^)[A-Z]/) { "_#{$&}" }.downcase
45
+ @runner_name ||= runner_class.to_s.split('::').last.gsub(/(?<!^)[A-Z]/) { "_#{Regexp.last_match(0)}" }.downcase
46
46
  end
47
47
 
48
48
  def runner_const
@@ -5,6 +5,34 @@ module Legion
5
5
  include Legion::Extensions::Helpers::Core
6
6
  include Legion::Extensions::Helpers::Logger
7
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
+
8
36
  def self.included(base)
9
37
  base.send :extend, Legion::Extensions::Helpers::Core if base.instance_of?(Class)
10
38
  base.send :extend, Legion::Extensions::Helpers::Logger if base.instance_of?(Class)
@@ -12,7 +40,7 @@ module Legion
12
40
  end
13
41
 
14
42
  def default_settings
15
- { logger: { level: 'info' }, workers: 1 }
43
+ { logger: { level: 'info' }, workers: 1, runners: {}, functions: {} }
16
44
  end
17
45
  end
18
46
  end