legionio 0.1.1
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 +7 -0
- data/.gitignore +14 -0
- data/.rubocop.yml +26 -0
- data/Gemfile +12 -0
- data/Rakefile +38 -0
- data/bin/console +15 -0
- data/bin/legion +58 -0
- data/bin/setup +8 -0
- data/bin/test +5 -0
- data/bitbucket-pipelines.yml +50 -0
- data/exe/legion +58 -0
- data/legion.gemspec +54 -0
- data/lib/legion.rb +12 -0
- data/lib/legion/exceptions/invalidjson.rb +8 -0
- data/lib/legion/exceptions/missingargument.rb +8 -0
- data/lib/legion/exceptions/wrongtype.rb +10 -0
- data/lib/legion/exceptions/wrongtypes/array.rb +11 -0
- data/lib/legion/exceptions/wrongtypes/hash.rb +11 -0
- data/lib/legion/exceptions/wrongtypes/integer.rb +11 -0
- data/lib/legion/exceptions/wrongtypes/string.rb +11 -0
- data/lib/legion/extension/loader.rb +96 -0
- data/lib/legion/process.rb +133 -0
- data/lib/legion/runners/runner.rb +58 -0
- data/lib/legion/service.rb +63 -0
- data/lib/legion/supervison.rb +28 -0
- data/lib/legion/version.rb +5 -0
- data/settings/client.json +9 -0
- metadata +295 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3cd9e6bd148a8733cf8c186fb864bd35d6d6595e
|
4
|
+
data.tar.gz: e0b3a6fe44495dd6d9de61785501e8e11c987d60
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 321681e4833fa124fc0be0e4223cec3aa253332b6d17bb31eeec176b83dd0d6a77eb7c828987e5f0385e40027dd1b56fde528fe58de1a3c0d4b7a1c53e56da75
|
7
|
+
data.tar.gz: 430ac9288323876d2035a5edf406c199e203220f46d3a1ac599dc7f66a68af82680df4b904c0f0dd6715cd0aad791d5df354a74f8065d90706731631ef90fd9a
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
Metrics/LineLength:
|
2
|
+
Max: 120
|
3
|
+
Metrics/MethodLength:
|
4
|
+
Max: 30
|
5
|
+
Metrics/ClassLength:
|
6
|
+
Max: 1500
|
7
|
+
Metrics/BlockLength:
|
8
|
+
Max: 50
|
9
|
+
Exclude:
|
10
|
+
Layout/SpaceAroundEqualsInParameterDefault:
|
11
|
+
EnforcedStyle: space
|
12
|
+
Style/SymbolArray:
|
13
|
+
Enabled: true
|
14
|
+
Layout/AlignHash:
|
15
|
+
EnforcedHashRocketStyle: table
|
16
|
+
EnforcedColonStyle: table
|
17
|
+
Style/HashSyntax:
|
18
|
+
EnforcedStyle: ruby19_no_mixed_keys
|
19
|
+
Style/Documentation:
|
20
|
+
Enabled: false
|
21
|
+
AllCops:
|
22
|
+
TargetRubyVersion: 2.4
|
23
|
+
Style/FrozenStringLiteralComment:
|
24
|
+
Enabled: false
|
25
|
+
Naming/FileName:
|
26
|
+
Enabled: false
|
data/Gemfile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# gem 'legion-json', path: '~/legion-io/legion-json'
|
4
|
+
# gem 'legion-transport', path: '~/legion-io/legion-transport'
|
5
|
+
# gem 'legion-extensions', path: '~/legion-io/legion-extensions'
|
6
|
+
# gem 'lex-tasker', path: '~/legion-io/legion-extensions-tasker'
|
7
|
+
# gem 'lex-conditioner', path: '~/legion-io/legion-extensions-conditioner'
|
8
|
+
# gem 'lex-transformer', path: '~/legion-io/legion-extensions-transformer'
|
9
|
+
# gem 'lex-logger', path: '~/legion-io/legion-extensions-logger'
|
10
|
+
|
11
|
+
# Specify your gem's dependencies in legion.gemspec
|
12
|
+
gemspec
|
data/Rakefile
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
|
6
|
+
RSpec::Core::RakeTask.new(:spec)
|
7
|
+
|
8
|
+
task default: :spec
|
9
|
+
|
10
|
+
task test: :rubocop
|
11
|
+
task test: :spec
|
12
|
+
task test: :start
|
13
|
+
|
14
|
+
task :rubocop do
|
15
|
+
sh 'rubocop'
|
16
|
+
end
|
17
|
+
|
18
|
+
task :start do
|
19
|
+
sh 'bin/legion start -d'
|
20
|
+
sh 'bin/legion stop'
|
21
|
+
end
|
22
|
+
|
23
|
+
namespace :deploy do
|
24
|
+
require 'legion/version.rb'
|
25
|
+
desc 'Deploy alpha/test'
|
26
|
+
task :test do
|
27
|
+
Gem.yank_gem('legion', "#{Legion::VERSION}a") if false
|
28
|
+
puts Gem.query('legion-transport').inspect
|
29
|
+
puts Gem.methods(false)
|
30
|
+
puts Legion::VERSION
|
31
|
+
end
|
32
|
+
|
33
|
+
task :staging do
|
34
|
+
end
|
35
|
+
|
36
|
+
task :production do
|
37
|
+
end
|
38
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'legion'
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require 'irb'
|
15
|
+
IRB.start(__FILE__)
|
data/bin/legion
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
# rubocop:disable all
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
options = { action: :run }
|
7
|
+
|
8
|
+
daemonize_help = 'run daemonized in the background (default: false)'
|
9
|
+
pidfile_help = 'the pid filename'
|
10
|
+
logfile_help = 'the log filename'
|
11
|
+
include_help = 'an additional $LOAD_PATH (may be used more than once)'
|
12
|
+
debug_help = 'set $DEBUG to true'
|
13
|
+
warn_help = 'enable warnings'
|
14
|
+
|
15
|
+
op = OptionParser.new
|
16
|
+
op.banner = 'An example of how to daemonize a long running Ruby process.'
|
17
|
+
op.separator ''
|
18
|
+
op.separator 'Usage: server [options]'
|
19
|
+
op.separator ''
|
20
|
+
|
21
|
+
op.separator ''
|
22
|
+
op.separator 'Process options:'
|
23
|
+
op.on('-d', '--daemonize', daemonize_help) { options[:daemonize] = true }
|
24
|
+
op.on('-p', '--pid PIDFILE', pidfile_help) { |value| options[:pidfile] = value }
|
25
|
+
op.on('-l', '--log LOGFILE', logfile_help) { |value| options[:logfile] = value }
|
26
|
+
|
27
|
+
op.separator ''
|
28
|
+
op.separator 'Ruby options:'
|
29
|
+
op.on('-I', '--include PATH', include_help) {
|
30
|
+
|value| $LOAD_PATH.unshift(*value.split(':').map {
|
31
|
+
|v| File.expand_path(v)
|
32
|
+
})
|
33
|
+
}
|
34
|
+
op.on('--debug', debug_help) { $DEBUG = true }
|
35
|
+
op.on('--warn', warn_help) { $-w = true }
|
36
|
+
|
37
|
+
op.separator ''
|
38
|
+
op.separator 'Common options:'
|
39
|
+
op.on('-h', '--help') { options[:action] = :help }
|
40
|
+
op.on('-v', '--version') { options[:action] = :version }
|
41
|
+
|
42
|
+
op.separator ''
|
43
|
+
op.parse!(ARGV)
|
44
|
+
|
45
|
+
#==============================================================================
|
46
|
+
# EXECUTE script
|
47
|
+
#==============================================================================
|
48
|
+
|
49
|
+
require File.expand_path('lib/legion.rb') unless options[:action] == :help
|
50
|
+
require File.expand_path('lib/legion/process.rb') unless options[:action] == :help
|
51
|
+
case options[:action]
|
52
|
+
when :help then puts op.to_s
|
53
|
+
when :version then puts Legion::VERSION
|
54
|
+
else
|
55
|
+
Legion::Process.run!(options)
|
56
|
+
end
|
57
|
+
|
58
|
+
Legion::Process.new(options).run!
|
data/bin/setup
ADDED
data/bin/test
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
image: ruby:2.4.0
|
2
|
+
|
3
|
+
pipelines:
|
4
|
+
branches:
|
5
|
+
master:
|
6
|
+
- step:
|
7
|
+
caches:
|
8
|
+
- bundler
|
9
|
+
script:
|
10
|
+
- gem install bundle rubocop
|
11
|
+
- bundle install
|
12
|
+
- rubocop
|
13
|
+
- rake
|
14
|
+
services:
|
15
|
+
- mysql
|
16
|
+
- broker
|
17
|
+
default:
|
18
|
+
- step:
|
19
|
+
caches:
|
20
|
+
- bundler
|
21
|
+
script:
|
22
|
+
- gem install bundle rubocop
|
23
|
+
- bundle install
|
24
|
+
- rubocop
|
25
|
+
- rake
|
26
|
+
services:
|
27
|
+
- mysql
|
28
|
+
- broker
|
29
|
+
- step:
|
30
|
+
name: Deploy to test
|
31
|
+
deployment: test
|
32
|
+
script:
|
33
|
+
definitions:
|
34
|
+
caches:
|
35
|
+
bundler: vendor/bundle
|
36
|
+
services:
|
37
|
+
mysql:
|
38
|
+
image: mysql:5.7
|
39
|
+
environment:
|
40
|
+
MYSQL_DATABASE: 'legion'
|
41
|
+
MYSQL_ROOT_PASSWORD: 'legion'
|
42
|
+
MYSQL_USER: 'legion'
|
43
|
+
MYSQL_PASSWORD: 'legion'
|
44
|
+
broker:
|
45
|
+
image: rabbitmq:3
|
46
|
+
environment:
|
47
|
+
RABBITMQ_DEFAULT_USER: guest
|
48
|
+
RABBITMQ_DEFAULT_PASS: guest
|
49
|
+
ports:
|
50
|
+
- 5672:5672
|
data/exe/legion
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env jruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
# rubocop:disable all
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
options = { action: :run }
|
7
|
+
|
8
|
+
daemonize_help = 'run daemonized in the background (default: false)'
|
9
|
+
pidfile_help = 'the pid filename'
|
10
|
+
logfile_help = 'the log filename'
|
11
|
+
include_help = 'an additional $LOAD_PATH (may be used more than once)'
|
12
|
+
debug_help = 'set $DEBUG to true'
|
13
|
+
warn_help = 'enable warnings'
|
14
|
+
|
15
|
+
op = OptionParser.new
|
16
|
+
op.banner = 'An example of how to daemonize a long running Ruby process.'
|
17
|
+
op.separator ''
|
18
|
+
op.separator 'Usage: server [options]'
|
19
|
+
op.separator ''
|
20
|
+
|
21
|
+
op.separator ''
|
22
|
+
op.separator 'Process options:'
|
23
|
+
op.on('-d', '--daemonize', daemonize_help) { options[:daemonize] = true }
|
24
|
+
op.on('-p', '--pid PIDFILE', pidfile_help) { |value| options[:pidfile] = value }
|
25
|
+
op.on('-l', '--log LOGFILE', logfile_help) { |value| options[:logfile] = value }
|
26
|
+
|
27
|
+
op.separator ''
|
28
|
+
op.separator 'Ruby options:'
|
29
|
+
op.on('-I', '--include PATH', include_help) {
|
30
|
+
|value| $LOAD_PATH.unshift(*value.split(':').map {
|
31
|
+
|v| File.expand_path(v)
|
32
|
+
})
|
33
|
+
}
|
34
|
+
op.on('--debug', debug_help) { $DEBUG = true }
|
35
|
+
op.on('--warn', warn_help) { $-w = true }
|
36
|
+
|
37
|
+
op.separator ''
|
38
|
+
op.separator 'Common options:'
|
39
|
+
op.on('-h', '--help') { options[:action] = :help }
|
40
|
+
op.on('-v', '--version') { options[:action] = :version }
|
41
|
+
|
42
|
+
op.separator ''
|
43
|
+
op.parse!(ARGV)
|
44
|
+
|
45
|
+
#==============================================================================
|
46
|
+
# EXECUTE script
|
47
|
+
#==============================================================================
|
48
|
+
|
49
|
+
require File.expand_path('lib/legion.rb') unless options[:action] == :help
|
50
|
+
require File.expand_path('lib/legion/process.rb') unless options[:action] == :help
|
51
|
+
case options[:action]
|
52
|
+
when :help then puts op.to_s
|
53
|
+
when :version then puts Legion::VERSION
|
54
|
+
else
|
55
|
+
Legion::Process.run!(options)
|
56
|
+
end
|
57
|
+
|
58
|
+
Legion::Process.new(options).run!
|
data/legion.gemspec
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'legion/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = (RUBY_ENGINE == 'jruby' ? 'legionio-java' : 'legionio')
|
9
|
+
spec.version = Legion::VERSION
|
10
|
+
spec.authors = ['Esity']
|
11
|
+
spec.email = ['matthewdiverson@gmail.com']
|
12
|
+
|
13
|
+
spec.summary = 'Legion Core Software to string it all together'
|
14
|
+
spec.description = 'Legion Core runs Legion Framwork'
|
15
|
+
spec.homepage = 'https://bitbucket.org/legion-io/legion/'
|
16
|
+
spec.license = 'MIT'
|
17
|
+
|
18
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
19
|
+
f.match(%r{^(test|spec|features)/})
|
20
|
+
end
|
21
|
+
spec.bindir = 'exe'
|
22
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
|
+
spec.require_paths = ['lib']
|
24
|
+
|
25
|
+
# if RUBY_ENGINE == 'jruby'
|
26
|
+
# spec.add_dependency 'legion-data-java', '~> 0.1'
|
27
|
+
# spec.add_dependency 'legion-json-java', '~> 0.1'
|
28
|
+
# spec.add_dependency 'legion-settings-java', '~> 0.1'
|
29
|
+
# spec.add_dependency 'legion-transport-java', '~> 0.1'
|
30
|
+
# else
|
31
|
+
# spec.add_dependency 'legion-data', '~> 0.1'
|
32
|
+
# spec.add_dependency 'legion-json', '~> 0.1'
|
33
|
+
# spec.add_dependency 'legion-settings', '~> 0.1'
|
34
|
+
# spec.add_dependency 'legion-transport', '~> 0.1'
|
35
|
+
# end
|
36
|
+
spec.add_dependency 'celluloid'
|
37
|
+
spec.add_dependency 'celluloid-io'
|
38
|
+
spec.add_dependency 'daemons'
|
39
|
+
spec.add_dependency 'legion-data', '~> 0.1'
|
40
|
+
spec.add_dependency 'legion-json', '~> 0.1'
|
41
|
+
spec.add_dependency 'legion-settings', '~> 0.1'
|
42
|
+
spec.add_dependency 'legion-transport', '~> 0.1'
|
43
|
+
|
44
|
+
spec.add_dependency 'legion-exceptions'
|
45
|
+
spec.add_dependency 'legion-extensions', '~> 0.1'
|
46
|
+
spec.add_dependency 'legion-logging', '~> 0.1'
|
47
|
+
|
48
|
+
spec.add_development_dependency 'bundler', '~> 1'
|
49
|
+
spec.add_development_dependency 'codecov'
|
50
|
+
spec.add_development_dependency 'rake'
|
51
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
52
|
+
spec.add_development_dependency 'rubocop'
|
53
|
+
spec.add_development_dependency 'simplecov'
|
54
|
+
end
|
data/lib/legion.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Process.setproctitle('Legion')
|
4
|
+
require 'legion/version'
|
5
|
+
require 'legion/process'
|
6
|
+
require 'legion/service'
|
7
|
+
|
8
|
+
# Base Legion Module to start the world
|
9
|
+
module Legion
|
10
|
+
Legion::Service.new({})
|
11
|
+
Legion::Logging.info("Started Legion v#{Legion::VERSION}")
|
12
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'legion/transport/messages/lex_register'
|
2
|
+
|
3
|
+
module Legion
|
4
|
+
module Extension
|
5
|
+
# New magical extension loader
|
6
|
+
class Loader
|
7
|
+
attr_reader :loaded_extensions
|
8
|
+
def initialize(supervision, _extensions = Legion::Settings[:legion][:extensions])
|
9
|
+
@loaded_extensions = []
|
10
|
+
@supervision = supervision
|
11
|
+
end
|
12
|
+
|
13
|
+
def load_extensions(extensions = Legion::Settings[:legion][:extensions])
|
14
|
+
extensions.each do |extension, values|
|
15
|
+
Legion::Logging.debug "Skipping #{extension} because it's disabled" unless values[:enabled]
|
16
|
+
next unless values[:enabled]
|
17
|
+
|
18
|
+
result = load_extension(extension, values)
|
19
|
+
Legion::Logging.info("#{extension} was loaded") if result
|
20
|
+
Legion::Logging.warn("#{extension} failed to load") unless result
|
21
|
+
@loaded_extensions.push(extension) if result
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def load_actor_pool(klass, name, size = 1)
|
26
|
+
@supervision.supervision_group.pool(klass, as: name, size: size)
|
27
|
+
end
|
28
|
+
|
29
|
+
def register_lex(_extension, lex_methods)
|
30
|
+
lex_methods.each do |namespace|
|
31
|
+
namespace[:class_methods].each do |class_method, _attrs|
|
32
|
+
options = { namespace: {}, method: {} }
|
33
|
+
options[:namespace][:queue] = namespace[:queue] unless namespace[:queue].nil?
|
34
|
+
options[:namespace][:uri] = namespace[:uri] unless namespace[:uri].nil?
|
35
|
+
Legion::Transport::Messages::LexRegister.new(namespace[:namespace], class_method, options).publish
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def load_extension(extension, values) # rubocop:disable Metrics/AbcSize
|
41
|
+
Legion::Logging.debug "Skipping #{extension} because it's disabled" unless values[:enabled]
|
42
|
+
return false unless values[:enabled]
|
43
|
+
|
44
|
+
unless gem_load(extension)
|
45
|
+
Legion::Logging.warn "#{extension} failed to load gem path"
|
46
|
+
return false
|
47
|
+
end
|
48
|
+
|
49
|
+
klass = Kernel.const_get(values[:class])
|
50
|
+
klass.autobuild
|
51
|
+
|
52
|
+
register_lex(extension, klass.lex_methods)
|
53
|
+
|
54
|
+
klass.actors.each do |actor|
|
55
|
+
load_actor_pool(actor[:class], actor[:group_name], 1)
|
56
|
+
end
|
57
|
+
true
|
58
|
+
rescue Sequel::DatabaseConnectionError => exception
|
59
|
+
Legion::Logging.fatal("Legion::Extension #{extension} requires a database connection but failed")
|
60
|
+
Legion::Logging.debug("Extension failed with #{exception.message}")
|
61
|
+
Legion::Logging.debug("Backtrace: #{exception.backtrace}")
|
62
|
+
false
|
63
|
+
rescue NameError => exception
|
64
|
+
Legion::Logging.fatal("Legion::Extension #{extension} failed to load, moving on without it")
|
65
|
+
Legion::Logging.warn("Extension failed with #{exception.message}")
|
66
|
+
Legion::Logging.warn("Backtrace: #{exception.backtrace}")
|
67
|
+
false
|
68
|
+
rescue LoadError => exception
|
69
|
+
Legion::Logging.fatal("Legion::Extension #{extension} failed to load, moving on without it")
|
70
|
+
Legion::Logging.warn("Extension failed with #{exception.message}")
|
71
|
+
Legion::Logging.warn("Backtrace: #{exception.backtrace}")
|
72
|
+
false
|
73
|
+
rescue StandardError => exception
|
74
|
+
Legion::Logging.fatal("Legion::Extension #{extension} failed to load, moving on without it")
|
75
|
+
Legion::Logging.fatal("#{extension} was caught by default")
|
76
|
+
Legion::Logging.warn("Extension failed with #{exception.message}")
|
77
|
+
Legion::Logging.warn("Backtrace: #{exception.backtrace}")
|
78
|
+
false
|
79
|
+
end
|
80
|
+
|
81
|
+
def gem_load(name)
|
82
|
+
search_name = 'lex-' + name.to_s
|
83
|
+
Legion::Logging.unknown search_name
|
84
|
+
gem_dir = Gem::Specification.find_by_name(search_name).gem_dir
|
85
|
+
Legion::Logging.unknown gem_dir
|
86
|
+
require "#{gem_dir}/lib/legion/extensions/#{name}"
|
87
|
+
true
|
88
|
+
rescue LoadError => ex
|
89
|
+
Legion::Logging.unknown ex.message
|
90
|
+
Legion::Logging.unknown ex.backtrace
|
91
|
+
Legion::Logging.warn "gem path: #{gem_dir}/lib/legion/extensions/#{name}"
|
92
|
+
false
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module Legion
|
6
|
+
# Responsible for starting the Legion process
|
7
|
+
class Process
|
8
|
+
def self.run!(options)
|
9
|
+
Legion::Process.new(options).run!
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :options, :quit, :service
|
13
|
+
|
14
|
+
def initialize(options)
|
15
|
+
@options = options
|
16
|
+
options[:logfile] = File.expand_path(logfile) if logfile?
|
17
|
+
options[:pidfile] = File.expand_path(pidfile) if pidfile?
|
18
|
+
end
|
19
|
+
|
20
|
+
def daemonize?
|
21
|
+
options[:daemonize]
|
22
|
+
end
|
23
|
+
|
24
|
+
def logfile
|
25
|
+
options[:logfile]
|
26
|
+
end
|
27
|
+
|
28
|
+
def pidfile
|
29
|
+
options[:pidfile]
|
30
|
+
end
|
31
|
+
|
32
|
+
def logfile?
|
33
|
+
!logfile.nil?
|
34
|
+
end
|
35
|
+
|
36
|
+
def pidfile?
|
37
|
+
!pidfile.nil?
|
38
|
+
end
|
39
|
+
|
40
|
+
def info(msg)
|
41
|
+
puts "[#{::Process.pid}] [#{Time.now}] #{msg}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def run!
|
45
|
+
check_pid
|
46
|
+
daemonize if daemonize?
|
47
|
+
write_pid
|
48
|
+
trap_signals
|
49
|
+
|
50
|
+
until quit
|
51
|
+
sleep(1) # in real life, something productive would happen here
|
52
|
+
end
|
53
|
+
# sleep(1)
|
54
|
+
# sleep(1)
|
55
|
+
Legion::Logging.info('Legion is shutting down!')
|
56
|
+
# @service.shutdown
|
57
|
+
Legion::Logging.info('Legion has shutdown. Goodbye!')
|
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
|
+
#==========================================================================
|
112
|
+
# SIGNAL HANDLING
|
113
|
+
#==========================================================================
|
114
|
+
|
115
|
+
def trap_signals
|
116
|
+
# trap(:QUIT) do # graceful shutdown
|
117
|
+
# info 'shutting down'
|
118
|
+
# @quit = true
|
119
|
+
# end
|
120
|
+
|
121
|
+
trap('SIGTERM') do
|
122
|
+
info 'sigterm'
|
123
|
+
end
|
124
|
+
|
125
|
+
trap('SIGHUP') do
|
126
|
+
info 'sithup'
|
127
|
+
end
|
128
|
+
trap('SIGINT') do
|
129
|
+
@quit = true
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'legion/transport/messages/task_check_subtask'
|
4
|
+
require 'legion/transport/messages/task_update'
|
5
|
+
|
6
|
+
module Legion
|
7
|
+
module Runner
|
8
|
+
# Base running class that will run everything
|
9
|
+
class Runner
|
10
|
+
def initialize(klass, method, options = {}) # rubocop:disable Metrics/AbcSize
|
11
|
+
klass = Kernel.const_get(klass) if klass.is_a? String
|
12
|
+
result = if options[:args].nil?
|
13
|
+
klass.send(method)
|
14
|
+
else
|
15
|
+
klass.send(method, options[:args])
|
16
|
+
end
|
17
|
+
update_status(options[:task_id]) unless options[:task_id].nil?
|
18
|
+
Legion::Transport::Messages::TaskCheckSubtask.new(klass, method, result, options).publish
|
19
|
+
rescue StandardError => ex
|
20
|
+
Legion::Logging.error(ex.message)
|
21
|
+
Legion::Logging.warn(ex.backtrace)
|
22
|
+
return if options[:task_id].nil?
|
23
|
+
|
24
|
+
update_status(options[:task_id], 'task.exception', msg: ex.message)
|
25
|
+
end
|
26
|
+
|
27
|
+
def update_status(_task_id, status = 'task.completed', options = {})
|
28
|
+
Legion::Transport::Messages::TaskUpdate.new(options[:task_id], status, options).publish
|
29
|
+
# if Legion::Settings[:data][:connected]
|
30
|
+
# update_status_database(task_id, status)
|
31
|
+
# else
|
32
|
+
# update_status_rmq(task_id, status)
|
33
|
+
# end
|
34
|
+
end
|
35
|
+
|
36
|
+
def update_status_rmq(_task_id, status = 'task.completed', options = {})
|
37
|
+
Legion::Transport::Messages::TaskUpdate.new(options[:task_id], status).publish
|
38
|
+
end
|
39
|
+
|
40
|
+
def update_status_database(task_id, _status = 'task.completed', _options = {})
|
41
|
+
require 'legion/data/models/task'
|
42
|
+
task = Legion::Data::Model::Task[task_id]
|
43
|
+
task.update(status: 'task.completed')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Status
|
50
|
+
# task.scheduled
|
51
|
+
# condition.queued
|
52
|
+
# condition.failed
|
53
|
+
# condition.succeeded
|
54
|
+
# condition.exception
|
55
|
+
# transformation.queued
|
56
|
+
# transformation.succeeded
|
57
|
+
# transformation.exception
|
58
|
+
# task.completed
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Legion
|
4
|
+
# Used for creating the actual legion service
|
5
|
+
class Service
|
6
|
+
def initialize(_options = {})
|
7
|
+
setup_logging
|
8
|
+
Legion::Logging.debug('Starting Legion::Service')
|
9
|
+
setup_settings
|
10
|
+
setup_transport
|
11
|
+
setup_sequel
|
12
|
+
setup_supervision
|
13
|
+
sleep(0.1)
|
14
|
+
load_extensions
|
15
|
+
end
|
16
|
+
|
17
|
+
def setup_sequel
|
18
|
+
require 'legion/data/connection'
|
19
|
+
Legion::Data::Connection.new
|
20
|
+
Legion::Data::Connection.new
|
21
|
+
Legion::Data::Connection.new
|
22
|
+
@connected = true
|
23
|
+
end
|
24
|
+
|
25
|
+
def setup_settings
|
26
|
+
require 'legion/settings'
|
27
|
+
Legion::Logging.debug('Loading Legion::Settings')
|
28
|
+
@settings = Legion::Settings.load(config_dir: './settings')
|
29
|
+
Legion::Logging.info('Legion::Settings Loaded')
|
30
|
+
end
|
31
|
+
|
32
|
+
def setup_logging
|
33
|
+
require 'legion/logging'
|
34
|
+
Legion::Logging.setup(level: 'info')
|
35
|
+
end
|
36
|
+
|
37
|
+
def setup_transport
|
38
|
+
require 'legion/transport'
|
39
|
+
require 'legion/transport/connection'
|
40
|
+
Legion::Transport::Connection.new
|
41
|
+
end
|
42
|
+
|
43
|
+
def setup_supervision
|
44
|
+
require 'celluloid/current'
|
45
|
+
Celluloid.logger = Legion::Logging
|
46
|
+
require_relative('supervison')
|
47
|
+
@supervision = Legion::Supervision.new
|
48
|
+
end
|
49
|
+
|
50
|
+
def shutdown
|
51
|
+
Legion::Logging.info('Legion::Service.shutdown was called')
|
52
|
+
@shutdown = true
|
53
|
+
@supervision.stop_supervision
|
54
|
+
Celluloid.shutdown
|
55
|
+
end
|
56
|
+
|
57
|
+
def load_extensions
|
58
|
+
require 'legion/runners/runner'
|
59
|
+
require 'legion/extension/loader'
|
60
|
+
Legion::Extension::Loader.new(@supervision).load_extensions
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'celluloid/io'
|
2
|
+
|
3
|
+
module Legion
|
4
|
+
# Used to manage and start Celluloid and Supervisor
|
5
|
+
class Supervision
|
6
|
+
attr_accessor :supervision_group
|
7
|
+
def initialize
|
8
|
+
Legion::Logging.debug('Initializing Legion::Supervision')
|
9
|
+
Legion::Logging.info('Starting Celluloid')
|
10
|
+
Celluloid.logger = Legion::Logging
|
11
|
+
start_supervision
|
12
|
+
end
|
13
|
+
|
14
|
+
def start_supervision
|
15
|
+
Legion::Logging.debug('Starting Celluloid::Supervision::Container.run!')
|
16
|
+
@supervision_group = Celluloid::Supervision::Container.run!
|
17
|
+
Legion::Logging.info('Celluloid Supervisor has started')
|
18
|
+
end
|
19
|
+
|
20
|
+
def stop_supervision
|
21
|
+
Legion::Logging.info('Shutting down the Supervision group')
|
22
|
+
@supervision_group.shutdown
|
23
|
+
sleep(1)
|
24
|
+
Celluloid.shutdown
|
25
|
+
Legion::Logging.info('Legion Celluloid Supervision Group has been shutdown')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,295 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: legionio
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Esity
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-02-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: celluloid
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: celluloid-io
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: daemons
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: legion-data
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.1'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.1'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: legion-json
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.1'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.1'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: legion-settings
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.1'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.1'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: legion-transport
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.1'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.1'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: legion-exceptions
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: legion-extensions
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.1'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0.1'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: legion-logging
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0.1'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0.1'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: bundler
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '1'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '1'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: codecov
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: rake
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: rspec
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - "~>"
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '3.0'
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - "~>"
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '3.0'
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
name: rubocop
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - ">="
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: '0'
|
216
|
+
type: :development
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - ">="
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '0'
|
223
|
+
- !ruby/object:Gem::Dependency
|
224
|
+
name: simplecov
|
225
|
+
requirement: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - ">="
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '0'
|
230
|
+
type: :development
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
requirements:
|
234
|
+
- - ">="
|
235
|
+
- !ruby/object:Gem::Version
|
236
|
+
version: '0'
|
237
|
+
description: Legion Core runs Legion Framwork
|
238
|
+
email:
|
239
|
+
- matthewdiverson@gmail.com
|
240
|
+
executables:
|
241
|
+
- legion
|
242
|
+
extensions: []
|
243
|
+
extra_rdoc_files: []
|
244
|
+
files:
|
245
|
+
- ".gitignore"
|
246
|
+
- ".rubocop.yml"
|
247
|
+
- Gemfile
|
248
|
+
- Rakefile
|
249
|
+
- bin/console
|
250
|
+
- bin/legion
|
251
|
+
- bin/setup
|
252
|
+
- bin/test
|
253
|
+
- bitbucket-pipelines.yml
|
254
|
+
- exe/legion
|
255
|
+
- legion.gemspec
|
256
|
+
- lib/legion.rb
|
257
|
+
- lib/legion/exceptions/invalidjson.rb
|
258
|
+
- lib/legion/exceptions/missingargument.rb
|
259
|
+
- lib/legion/exceptions/wrongtype.rb
|
260
|
+
- lib/legion/exceptions/wrongtypes/array.rb
|
261
|
+
- lib/legion/exceptions/wrongtypes/hash.rb
|
262
|
+
- lib/legion/exceptions/wrongtypes/integer.rb
|
263
|
+
- lib/legion/exceptions/wrongtypes/string.rb
|
264
|
+
- lib/legion/extension/loader.rb
|
265
|
+
- lib/legion/process.rb
|
266
|
+
- lib/legion/runners/runner.rb
|
267
|
+
- lib/legion/service.rb
|
268
|
+
- lib/legion/supervison.rb
|
269
|
+
- lib/legion/version.rb
|
270
|
+
- settings/client.json
|
271
|
+
homepage: https://bitbucket.org/legion-io/legion/
|
272
|
+
licenses:
|
273
|
+
- MIT
|
274
|
+
metadata: {}
|
275
|
+
post_install_message:
|
276
|
+
rdoc_options: []
|
277
|
+
require_paths:
|
278
|
+
- lib
|
279
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
280
|
+
requirements:
|
281
|
+
- - ">="
|
282
|
+
- !ruby/object:Gem::Version
|
283
|
+
version: '0'
|
284
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
285
|
+
requirements:
|
286
|
+
- - ">="
|
287
|
+
- !ruby/object:Gem::Version
|
288
|
+
version: '0'
|
289
|
+
requirements: []
|
290
|
+
rubyforge_project:
|
291
|
+
rubygems_version: 2.6.14
|
292
|
+
signing_key:
|
293
|
+
specification_version: 4
|
294
|
+
summary: Legion Core Software to string it all together
|
295
|
+
test_files: []
|