ragent 0.0.3 → 0.0.4
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/.rubocop.yml +3 -0
- data/Gemfile +2 -1
- data/Gemfile.lock +5 -3
- data/Rakefile +4 -3
- data/examples/Gemfile +2 -3
- data/examples/config.ragent +3 -3
- data/examples/lib/ragent/plugin/login.rb +3 -3
- data/examples/lib/ragent/plugin/time_bomb/bomb.rb +28 -0
- data/examples/lib/ragent/plugin/time_bomb.rb +11 -44
- data/exe/ragent +3 -8
- data/lib/ragent/cli.rb +46 -0
- data/lib/ragent/command.rb +11 -7
- data/lib/ragent/command_helpers.rb +20 -0
- data/lib/ragent/commands.rb +25 -18
- data/lib/ragent/configurator.rb +25 -0
- data/lib/ragent/logging.rb +13 -13
- data/lib/ragent/plugin.rb +32 -8
- data/lib/ragent/plugins.rb +16 -20
- data/lib/ragent/version.rb +2 -2
- data/lib/ragent.rb +50 -45
- data/ragent.gemspec +22 -20
- metadata +22 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 191cb56fece3b2f00ba49ecf91f182cfd9619958
|
4
|
+
data.tar.gz: da425f06681e2593c2193c7135ce94da2bb69098
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: efc8b9d1d9b87ba3fd4d02b8dbada0b1d715e94c0b53cd7f2781ee28bcbe265dcf1548bdff67de3459597574868a6267a738063307ec7d34420b2350bddbf91d
|
7
|
+
data.tar.gz: eb2c4532db49eb0c22286e6bdcc5a690e9e32ed36d25d08adcbc967969c454532052cbd143b1c9c375dd2b2ba4034b5e1e8bbf72a5a2f66a2d1a032f8b4abb95
|
data/.rubocop.yml
ADDED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ragent (0.0.
|
4
|
+
ragent (0.0.4)
|
5
5
|
celluloid (~> 0.17.0)
|
6
|
-
logging (~> 2.1
|
6
|
+
logging (~> 2.1)
|
7
|
+
thor (~> 0.19)
|
7
8
|
|
8
9
|
GEM
|
9
10
|
remote: https://rubygems.org/
|
@@ -46,6 +47,7 @@ GEM
|
|
46
47
|
diff-lcs (>= 1.2.0, < 2.0)
|
47
48
|
rspec-support (~> 3.5.0)
|
48
49
|
rspec-support (3.5.0)
|
50
|
+
thor (0.19.4)
|
49
51
|
timers (4.1.2)
|
50
52
|
hitimes
|
51
53
|
|
@@ -59,4 +61,4 @@ DEPENDENCIES
|
|
59
61
|
rspec (~> 3.0)
|
60
62
|
|
61
63
|
BUNDLED WITH
|
62
|
-
1.
|
64
|
+
1.14.3
|
data/Rakefile
CHANGED
data/examples/Gemfile
CHANGED
data/examples/config.ragent
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'celluloid/current'
|
2
3
|
require 'celluloid/io'
|
3
4
|
|
@@ -7,8 +8,7 @@ module Ragent
|
|
7
8
|
include Ragent::Plugin
|
8
9
|
include Celluloid::IO
|
9
10
|
|
10
|
-
|
11
|
-
end
|
11
|
+
plugin_name 'login'
|
12
12
|
|
13
13
|
def start
|
14
14
|
@server = TCPServer.new('127.0.0.1', 6666)
|
@@ -16,7 +16,7 @@ module Ragent
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def stop
|
19
|
-
@server
|
19
|
+
@server&.close
|
20
20
|
end
|
21
21
|
|
22
22
|
private
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Ragent
|
3
|
+
module Plugin
|
4
|
+
class TimeBomb
|
5
|
+
class Bomb
|
6
|
+
include Celluloid
|
7
|
+
include Celluloid::Notifications
|
8
|
+
include Ragent::Logging
|
9
|
+
|
10
|
+
finalizer :stop
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
async.start
|
14
|
+
end
|
15
|
+
|
16
|
+
def start
|
17
|
+
every(5) do
|
18
|
+
publish 'time-bomb-boom', expode_at: Time.now
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def stop
|
23
|
+
info 'disarmed'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -1,53 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative 'time_bomb/bomb'
|
3
|
+
|
1
4
|
module Ragent
|
2
5
|
module Plugin
|
3
6
|
class TimeBomb
|
4
|
-
class TestBomb
|
5
|
-
include Celluloid
|
6
|
-
include Celluloid::Notifications
|
7
|
-
include Ragent::Logging
|
8
|
-
|
9
|
-
finalizer :stop
|
10
|
-
|
11
|
-
def initialize
|
12
|
-
async.start
|
13
|
-
end
|
14
|
-
|
15
|
-
def start
|
16
|
-
every(5) do
|
17
|
-
publish 'time-bomb-boom', expode_at: Time.now
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def stop
|
22
|
-
info 'disarmed'
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
7
|
include Ragent::Plugin
|
27
8
|
|
28
|
-
|
9
|
+
plugin_name 'time_bomb'
|
10
|
+
commands :tick, :list, :disarm
|
11
|
+
|
12
|
+
def configure(*_args)
|
29
13
|
@next_time_bomb_id = 1
|
30
14
|
@time_bombs = {}
|
31
|
-
command('tick', :command_tick)
|
32
|
-
command('list', :command_list)
|
33
|
-
command('disarm', :command_disarm)
|
34
15
|
subscribe('time-bomb-boom', :boom_callback)
|
35
16
|
end
|
36
17
|
|
37
|
-
def start
|
38
|
-
end
|
39
|
-
|
40
|
-
def command(sub, method)
|
41
|
-
cmd = Ragent::Command.new(main: 'time_bomb',
|
42
|
-
sub: sub,
|
43
|
-
recipient: self,
|
44
|
-
method: method)
|
45
|
-
@ragent.commands.add(cmd)
|
46
|
-
end
|
47
|
-
|
48
18
|
def command_disarm(options)
|
49
19
|
bomb_name = "time_bomb_#{options['bomb']}"
|
50
|
-
bomb =
|
20
|
+
bomb = agents(bomb_name)
|
51
21
|
if bomb
|
52
22
|
bomb.terminate
|
53
23
|
@time_bombs.delete(bomb_name)
|
@@ -55,7 +25,7 @@ module Ragent
|
|
55
25
|
else
|
56
26
|
"no such bomb #{bomb_name}"
|
57
27
|
end
|
58
|
-
|
28
|
+
end
|
59
29
|
|
60
30
|
def command_list(_options)
|
61
31
|
@time_bombs.keys.join("\n")
|
@@ -67,12 +37,9 @@ module Ragent
|
|
67
37
|
@time_bombs[as] = true
|
68
38
|
@next_time_bomb_id += 1
|
69
39
|
|
70
|
-
|
71
|
-
type: TimeBomb::TestBomb,
|
72
|
-
as: as
|
73
|
-
)
|
40
|
+
agent(type: TimeBomb::Bomb, as: as)
|
74
41
|
|
75
|
-
|
42
|
+
"starting #{as}"
|
76
43
|
end
|
77
44
|
|
78
45
|
def boom_callback(_topic, params)
|
data/exe/ragent
CHANGED
@@ -1,12 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require_relative '../lib/ragent'
|
5
|
+
require_relative '../lib/ragent/cli'
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
ragent=Ragent.setup(
|
8
|
-
log_level: ENV['RAGENT_LOG_LEVEL'] || 'info',
|
9
|
-
workdir: workdir
|
10
|
-
)
|
11
|
-
|
12
|
-
eval File.read(ragent.workdir.join("config.ragent"))
|
7
|
+
Ragent::Cli::Main.start(ARGV)
|
data/lib/ragent/cli.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'thor'
|
3
|
+
|
4
|
+
module Ragent
|
5
|
+
module Cli
|
6
|
+
class Main < ::Thor
|
7
|
+
desc 'start', 'starts the ragent framweork reading your config.ragent file'
|
8
|
+
option :log_level, banner: '<debug|info|warn|error|fatal> overrides ENV RAGENT_LOG_LEVEL'
|
9
|
+
option :root, banner: '<DIR> the root of the app (default is the pwd)'
|
10
|
+
def start
|
11
|
+
Ragent.start(workdir: options[:root],
|
12
|
+
log_level: options[:log_level],
|
13
|
+
blocking: true)
|
14
|
+
end
|
15
|
+
|
16
|
+
long_desc <<-LONGDESC
|
17
|
+
ragent console will start an irb console in your terminal. CAUTION when exiting the console
|
18
|
+
currently the agent won't shutdown cleanly.
|
19
|
+
LONGDESC
|
20
|
+
desc 'console', 'start your application but gives you a console'
|
21
|
+
option :log_level, banner: '<debug|info|warn|error|fatal> overrides ENV RAGENT_LOG_LEVEL'
|
22
|
+
option :root, banner: '<DIR> the root of the app (default is the pwd)'
|
23
|
+
def console
|
24
|
+
Ragent.start(workdir: options[:root],
|
25
|
+
log_level: options[:log_level],
|
26
|
+
blocking: false)
|
27
|
+
require 'irb'
|
28
|
+
ARGV.clear # see http://stackoverflow.com/questions/33070092/irb-start-not-starting
|
29
|
+
IRB.start
|
30
|
+
end
|
31
|
+
|
32
|
+
# def plugin
|
33
|
+
# puts "TBD: create a new plugin structure"
|
34
|
+
# end
|
35
|
+
|
36
|
+
# def new
|
37
|
+
# puts "TBD: create a new ragent app"
|
38
|
+
# end
|
39
|
+
|
40
|
+
desc 'version', 'prints version of metoda-cli'
|
41
|
+
def version
|
42
|
+
puts Ragent::VERSION.to_s
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/ragent/command.rb
CHANGED
@@ -1,19 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Ragent
|
2
3
|
class Command
|
3
|
-
|
4
4
|
include Ragent::Logging
|
5
5
|
|
6
6
|
attr_reader :main, :sub
|
7
7
|
def initialize(main:, sub: nil, recipient:, method:)
|
8
|
-
@main=main
|
9
|
-
@sub=sub
|
10
|
-
@recipient=recipient
|
11
|
-
@method=method
|
8
|
+
@main = main.to_s
|
9
|
+
@sub = sub.to_s
|
10
|
+
@recipient = recipient
|
11
|
+
@method = method
|
12
12
|
end
|
13
13
|
|
14
|
-
def execute(options={})
|
14
|
+
def execute(options = {})
|
15
15
|
info "running: #{@main} #{@sub}, calling: #{@method}"
|
16
|
-
@recipient.send(@method,options)
|
16
|
+
@recipient.send(@method, options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def sub?
|
20
|
+
!sub.empty?
|
17
21
|
end
|
18
22
|
|
19
23
|
def help
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Ragent
|
3
|
+
module CommandHelpers
|
4
|
+
def command(*commands)
|
5
|
+
@prepared_commands = []
|
6
|
+
commands.each do |command|
|
7
|
+
prep_command = { main: plugin_name, # name of the plugin
|
8
|
+
sub: command,
|
9
|
+
method: "command_#{command}" }
|
10
|
+
@prepared_commands << prep_command
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def prepared_commands
|
15
|
+
@prepared_commands || []
|
16
|
+
end
|
17
|
+
|
18
|
+
alias commands command
|
19
|
+
end
|
20
|
+
end
|
data/lib/ragent/commands.rb
CHANGED
@@ -1,43 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Ragent
|
2
3
|
class Commands
|
3
4
|
include Ragent::Logging
|
4
5
|
|
5
6
|
def initialize(ragent)
|
6
|
-
@ragent=ragent
|
7
|
-
@commands={}
|
7
|
+
@ragent = ragent
|
8
|
+
@commands = {}
|
8
9
|
add_help_command
|
9
10
|
end
|
10
11
|
|
11
12
|
def add(command)
|
12
|
-
if command.sub
|
13
|
+
if command.sub?
|
13
14
|
@commands[command.main] ||= {}
|
14
|
-
@commands[command.main][command.sub]=command
|
15
|
+
@commands[command.main][command.sub] = command
|
15
16
|
else
|
16
17
|
@commands[command.main] ||= command
|
17
18
|
end
|
18
19
|
info "registered command: #{command.help}"
|
19
20
|
end
|
20
21
|
|
21
|
-
def lookup(main,sub,options)
|
22
|
+
def lookup(main, sub, options)
|
22
23
|
debug "checkig command: #{main},#{sub},#{options}"
|
23
|
-
cmd
|
24
|
+
cmd = @commands[main]
|
24
25
|
if cmd
|
25
|
-
|
26
|
-
|
26
|
+
|
27
|
+
if cmd.is_a?(Hash) && sub
|
28
|
+
sub_cmd = @commands[main][sub]
|
29
|
+
if sub_cmd
|
30
|
+
debug "command found (#{main},#{sub})"
|
31
|
+
else
|
32
|
+
debug "command not found (#{main},#{sub})"
|
33
|
+
end
|
34
|
+
return sub_cmd
|
27
35
|
else
|
36
|
+
debug "command found (#{main})"
|
28
37
|
return cmd
|
29
38
|
end
|
39
|
+
else
|
40
|
+
debug 'command not found'
|
30
41
|
end
|
31
42
|
nil
|
32
43
|
end
|
44
|
+
|
33
45
|
private
|
34
46
|
|
35
|
-
def help_command(
|
47
|
+
def help_command(_options = {})
|
36
48
|
@commands.values.map do |subs|
|
37
|
-
if subs.
|
38
|
-
subs.values.map
|
39
|
-
cmd.help
|
40
|
-
end
|
49
|
+
if subs.is_a?(Hash)
|
50
|
+
subs.values.map(&:help)
|
41
51
|
else
|
42
52
|
subs.help
|
43
53
|
end
|
@@ -46,11 +56,8 @@ module Ragent
|
|
46
56
|
|
47
57
|
def add_help_command
|
48
58
|
add(Ragent::Command.new(main: 'help',
|
49
|
-
|
50
|
-
|
51
|
-
))
|
59
|
+
recipient: self,
|
60
|
+
method: :help_command))
|
52
61
|
end
|
53
|
-
|
54
|
-
|
55
62
|
end
|
56
63
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Ragent
|
3
|
+
class Configurator
|
4
|
+
include Ragent::Logging
|
5
|
+
|
6
|
+
def initialize(ragent)
|
7
|
+
@ragent = ragent
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.load(ragent, filename)
|
11
|
+
config = new(ragent)
|
12
|
+
config._load(filename)
|
13
|
+
end
|
14
|
+
|
15
|
+
def _load(filename)
|
16
|
+
instance_eval File.read(filename)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def plugin(*args, &block)
|
22
|
+
@ragent.add_plugin(*args, &block)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/ragent/logging.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Ragent
|
2
3
|
module Logging
|
3
|
-
|
4
4
|
def self.logger=(logger)
|
5
|
-
@logger=logger
|
5
|
+
@logger = logger
|
6
6
|
end
|
7
7
|
|
8
8
|
def self.logger
|
@@ -13,20 +13,20 @@ module Ragent
|
|
13
13
|
Ragent::Logging.logger
|
14
14
|
end
|
15
15
|
|
16
|
-
def debug
|
17
|
-
|
16
|
+
def debug(str)
|
17
|
+
logger.debug(str)
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
def warn(str)
|
21
|
+
logger.warn(str)
|
22
|
+
end
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
def info(str)
|
25
|
+
logger.info(str)
|
26
|
+
end
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
def error(str)
|
29
|
+
logger.error(str)
|
30
|
+
end
|
31
31
|
end
|
32
32
|
end
|
data/lib/ragent/plugin.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Ragent
|
2
3
|
module Plugin
|
3
4
|
def self.included(klass)
|
@@ -5,19 +6,42 @@ module Ragent
|
|
5
6
|
klass.send(:include, Celluloid)
|
6
7
|
klass.send(:include, Celluloid::Notifications)
|
7
8
|
klass.send(:finalizer, :stop)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
9
|
+
klass.send(:extend, Ragent::CommandHelpers)
|
10
|
+
klass.extend(ClassMethods)
|
11
|
+
end
|
12
12
|
|
13
|
-
|
13
|
+
module ClassMethods
|
14
|
+
def plugin_name(name = nil)
|
15
|
+
if name
|
16
|
+
@name = name
|
17
|
+
else
|
18
|
+
@name
|
19
|
+
end
|
14
20
|
end
|
15
|
-
|
16
|
-
|
21
|
+
end
|
22
|
+
def initialize(ragent)
|
23
|
+
@ragent = ragent
|
24
|
+
@logger = ragent.logger
|
25
|
+
self.class.prepared_commands.each do |cmd|
|
26
|
+
@ragent.commands.add(cmd = Ragent::Command.new(cmd.merge(recipient: self)))
|
17
27
|
end
|
18
28
|
end
|
19
29
|
|
30
|
+
def configure(*args, &block); end
|
20
31
|
|
21
|
-
|
32
|
+
def start; end
|
22
33
|
|
34
|
+
def stop; end
|
35
|
+
|
36
|
+
def agent(type:, as:)
|
37
|
+
@ragent.supervisor.supervise(
|
38
|
+
type: type,
|
39
|
+
as: as
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def agents(name)
|
44
|
+
Celluloid::Actor[name]
|
45
|
+
end
|
46
|
+
end
|
23
47
|
end
|
data/lib/ragent/plugins.rb
CHANGED
@@ -1,24 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# Ragent::Plugin is reserved for plugins!
|
2
3
|
module Ragent
|
3
4
|
class Plugins
|
4
5
|
include Ragent::Logging
|
5
6
|
|
6
7
|
def initialize(ragent)
|
7
|
-
@ragent=ragent
|
8
|
-
@logger=ragent.logger
|
9
|
-
@plugins={}
|
10
|
-
@running_plugins=[]
|
8
|
+
@ragent = ragent
|
9
|
+
@logger = ragent.logger
|
10
|
+
@plugins = {}
|
11
|
+
@running_plugins = []
|
11
12
|
end
|
12
13
|
|
13
|
-
def load(name
|
14
|
+
def load(name, *args, &block)
|
14
15
|
info "loading plugin #{name}"
|
15
16
|
require "ragent/plugin/#{name}"
|
16
17
|
raise "plugin #{name} didn't register" unless @plugins[name.to_s]
|
17
18
|
info "loaded plugin #{name}"
|
18
|
-
#TODO: load and configure dependencies
|
19
|
-
plugin
|
19
|
+
# TODO: load and configure dependencies
|
20
|
+
plugin = @plugins[name.to_s]
|
20
21
|
info "Configure: #{plugin.name}"
|
21
|
-
running_plugin=plugin.new(@ragent)
|
22
|
+
running_plugin = plugin.new(@ragent)
|
22
23
|
running_plugin.configure(*args, &block)
|
23
24
|
debug "Configured: #{plugin.name}"
|
24
25
|
@running_plugins << running_plugin
|
@@ -29,12 +30,7 @@ module Ragent
|
|
29
30
|
end
|
30
31
|
|
31
32
|
def start
|
32
|
-
@running_plugins.each
|
33
|
-
info "Starting: #{plugin.name}"
|
34
|
-
# TODO: start dependencies
|
35
|
-
plugin.start
|
36
|
-
debug "Started: #{plugin.name}"
|
37
|
-
end
|
33
|
+
@running_plugins.each(&:start)
|
38
34
|
end
|
39
35
|
|
40
36
|
def stop
|
@@ -49,15 +45,15 @@ module Ragent
|
|
49
45
|
|
50
46
|
def register_commands
|
51
47
|
# stop
|
52
|
-
cmd=Ragent::Command.new(main: 'plugins',
|
53
|
-
|
54
|
-
|
55
|
-
|
48
|
+
cmd = Ragent::Command.new(main: 'plugins',
|
49
|
+
sub: 'list',
|
50
|
+
recipient: self,
|
51
|
+
method: :plugins_list_command)
|
56
52
|
@ragent.commands.add(cmd)
|
57
53
|
end
|
58
54
|
|
59
|
-
def plugins_list_command(
|
60
|
-
@plugins.values.map
|
55
|
+
def plugins_list_command(_options)
|
56
|
+
@plugins.values.map(&:name).join("\n")
|
61
57
|
end
|
62
58
|
end
|
63
59
|
end
|
data/lib/ragent/version.rb
CHANGED
data/lib/ragent.rb
CHANGED
@@ -1,36 +1,36 @@
|
|
1
|
-
#
|
2
|
-
#require 'eventmachine'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
require 'thread'
|
4
3
|
require 'celluloid/current'
|
5
4
|
require 'celluloid/autostart'
|
6
5
|
|
7
|
-
#require 'active_support/inflector'
|
8
|
-
|
9
6
|
require 'logging'
|
10
7
|
require 'pathname'
|
11
8
|
|
9
|
+
require_relative 'ragent/version'
|
12
10
|
require_relative 'ragent/logging'
|
13
11
|
require_relative 'ragent/plugins'
|
14
12
|
require_relative 'ragent/plugin'
|
15
13
|
require_relative 'ragent/commands'
|
16
14
|
require_relative 'ragent/command'
|
15
|
+
require_relative 'ragent/configurator'
|
16
|
+
require_relative 'ragent/command_helpers'
|
17
17
|
|
18
18
|
module Ragent
|
19
|
-
|
20
|
-
@ragent
|
21
|
-
end
|
19
|
+
DEFAULT_LOG_LEVEL = 'info'
|
22
20
|
|
23
|
-
def self.
|
24
|
-
|
21
|
+
def self.start(workdir: nil, log_level: nil, blocking: true)
|
22
|
+
Ragent.setup(
|
23
|
+
log_level: ENV['RAGENT_LOG_LEVEL'] || log_level || DEFAULT_LOG_LEVEL,
|
24
|
+
workdir: workdir || Dir.pwd
|
25
|
+
).config.run(blocking)
|
25
26
|
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
@ragent.plugins.load(name,*args, &block) if name.is_a?(Symbol)
|
28
|
+
def self.ragent
|
29
|
+
@ragent
|
30
30
|
end
|
31
31
|
|
32
|
-
def self.
|
33
|
-
@ragent.
|
32
|
+
def self.setup(*args)
|
33
|
+
@ragent = Agent.new(*args)
|
34
34
|
end
|
35
35
|
|
36
36
|
class Agent
|
@@ -42,55 +42,62 @@ module Ragent
|
|
42
42
|
attr_reader :plugins
|
43
43
|
|
44
44
|
def initialize(log_level:, workdir:)
|
45
|
-
@workdir=Pathname.new(workdir)
|
46
|
-
|
45
|
+
@workdir = Pathname.new(workdir)
|
46
|
+
$LOAD_PATH << @workdir.join('lib').to_s
|
47
47
|
|
48
|
-
|
49
|
-
Ragent::Logging.logger
|
48
|
+
# setup logger
|
49
|
+
Ragent::Logging.logger = ::Logging.logger['ragent']
|
50
50
|
logger.add_appenders ::Logging.appenders.stdout
|
51
51
|
|
52
|
-
@commands=Ragent::Commands.new(self)
|
52
|
+
@commands = Ragent::Commands.new(self)
|
53
|
+
@plugins = Plugins.new(self)
|
54
|
+
|
53
55
|
register_commands
|
54
|
-
@plugins=Plugins.new(self)
|
55
56
|
end
|
56
57
|
|
57
|
-
def
|
58
|
+
def config
|
59
|
+
Ragent::Configurator.load(self, workdir.join('config.ragent'))
|
60
|
+
self
|
61
|
+
end
|
62
|
+
|
63
|
+
def add_plugin(name, *args, &block)
|
64
|
+
plugins.load(name, *args, &block) if name.is_a?(Symbol)
|
65
|
+
end
|
66
|
+
|
67
|
+
def run(blocking = true)
|
58
68
|
@supervisor = Celluloid::Supervision::Container.run!
|
69
|
+
plugins.start
|
70
|
+
term_wait_loop if blocking
|
71
|
+
end
|
59
72
|
|
73
|
+
private
|
60
74
|
|
75
|
+
def term_wait_loop
|
61
76
|
self_read, @self_write = IO.pipe
|
62
|
-
|
63
77
|
%w(TERM TTIN INT).each do |sig|
|
64
78
|
Signal.trap sig do
|
65
79
|
@self_write.puts(sig)
|
66
80
|
end
|
67
81
|
end
|
68
|
-
|
69
|
-
#start_em
|
70
|
-
@plugins.start
|
71
|
-
|
72
|
-
stop=false
|
82
|
+
stop = false
|
73
83
|
while stop || readable_io = IO.select([self_read])
|
74
84
|
signal = readable_io.first[0].gets.strip
|
75
|
-
|
76
|
-
exit(0)
|
85
|
+
break if handle_signal(signal)
|
77
86
|
end
|
87
|
+
info 'Exiting'
|
78
88
|
end
|
79
89
|
|
80
|
-
private
|
81
|
-
|
82
|
-
#def start_em
|
83
90
|
# EM.epoll
|
84
91
|
# Thread.new { EventMachine.run } unless EventMachine.reactor_running?
|
85
92
|
# sleep 0.01 until EventMachine.reactor_running?
|
86
|
-
#end
|
93
|
+
# end
|
87
94
|
|
88
95
|
def handle_signal(signal)
|
89
96
|
info "Got signal #{signal}"
|
90
97
|
case signal
|
91
|
-
when 'TERM','INT'
|
92
|
-
info
|
93
|
-
EM.stop if EventMachine.reactor_running?
|
98
|
+
when 'TERM', 'INT', 'SHUTDOWN' # shutdown is an internal command
|
99
|
+
info 'Shutting down...'
|
100
|
+
# EM.stop if EventMachine.reactor_running?
|
94
101
|
@plugins.stop
|
95
102
|
@supervisor.shutdown
|
96
103
|
true
|
@@ -100,24 +107,22 @@ module Ragent
|
|
100
107
|
if thread.backtrace
|
101
108
|
warn thread.backtrace.join("\n")
|
102
109
|
else
|
103
|
-
warn
|
110
|
+
warn 'no backtrace available'
|
104
111
|
end
|
105
112
|
end
|
106
113
|
false
|
107
114
|
end
|
108
115
|
end
|
109
116
|
|
110
|
-
|
111
|
-
|
112
|
-
@self_write.puts("TERM")
|
117
|
+
def shutdown_command(_options = {})
|
118
|
+
@self_write.puts('SHUTDOWN')
|
113
119
|
end
|
114
120
|
|
115
121
|
def register_commands
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
method: :shutdown_command)
|
122
|
+
cmd = Ragent::Command.new(main: 'shutdown',
|
123
|
+
sub: nil,
|
124
|
+
recipient: self,
|
125
|
+
method: :shutdown_command)
|
121
126
|
@commands.add(cmd)
|
122
127
|
end
|
123
128
|
end
|
data/ragent.gemspec
CHANGED
@@ -1,43 +1,45 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
lib = File.expand_path('../lib', __FILE__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'ragent/version'
|
5
6
|
|
6
7
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
8
|
+
spec.name = 'ragent'
|
8
9
|
spec.version = Ragent::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
10
|
+
spec.authors = ['Peter Schrammel']
|
11
|
+
spec.email = ['peter.schrammel@gmx.de']
|
11
12
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
14
|
-
spec.homepage =
|
15
|
-
spec.license =
|
13
|
+
spec.summary = 'An agent framework'
|
14
|
+
spec.description = 'Writing of agents for monitoring, chatting, ... should be easy. Ragent eases this with a small extraction layer over celluloid.'
|
15
|
+
spec.homepage = 'https://github.com/pschrammel/ragent'
|
16
|
+
spec.license = 'MIT'
|
16
17
|
|
17
18
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
19
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
20
|
if spec.respond_to?(:metadata)
|
20
|
-
spec.metadata['allowed_push_host'] =
|
21
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
21
22
|
else
|
22
|
-
raise
|
23
|
-
|
23
|
+
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
24
|
+
'public gem pushes.'
|
24
25
|
end
|
25
26
|
|
26
|
-
spec.files
|
27
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
27
28
|
f.match(%r{^(test|spec|features)/})
|
28
29
|
end
|
29
|
-
spec.bindir =
|
30
|
+
spec.bindir = 'exe'
|
30
31
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
31
|
-
spec.require_paths = [
|
32
|
+
spec.require_paths = ['lib']
|
32
33
|
|
33
34
|
spec.add_dependency 'celluloid', '~>0.17.0'
|
34
|
-
|
35
|
-
# spec.add_dependency '
|
36
|
-
# spec.add_dependency '
|
35
|
+
spec.add_dependency 'thor', '~>0.19'
|
36
|
+
# spec.add_dependency 'activesupport'
|
37
|
+
# spec.add_dependency 'eventmachine'
|
38
|
+
# spec.add_dependency 'faye-websocket'
|
37
39
|
spec.add_dependency 'logging', '~>2.1'
|
38
|
-
# spec.add_dependency 'celluloid-io' #needed for a plugin, should be removed
|
40
|
+
# spec.add_dependency 'celluloid-io' #needed for a plugin, should be removed
|
39
41
|
|
40
|
-
spec.add_development_dependency
|
41
|
-
spec.add_development_dependency
|
42
|
-
spec.add_development_dependency
|
42
|
+
spec.add_development_dependency 'bundler', '~> 1.13'
|
43
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
44
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
43
45
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ragent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Schrammel
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-02-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: celluloid
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.17.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: thor
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.19'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.19'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: logging
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -90,6 +104,7 @@ extensions: []
|
|
90
104
|
extra_rdoc_files: []
|
91
105
|
files:
|
92
106
|
- ".gitignore"
|
107
|
+
- ".rubocop.yml"
|
93
108
|
- CODE_OF_CONDUCT.md
|
94
109
|
- Gemfile
|
95
110
|
- Gemfile.lock
|
@@ -101,10 +116,14 @@ files:
|
|
101
116
|
- examples/config.ragent
|
102
117
|
- examples/lib/ragent/plugin/login.rb
|
103
118
|
- examples/lib/ragent/plugin/time_bomb.rb
|
119
|
+
- examples/lib/ragent/plugin/time_bomb/bomb.rb
|
104
120
|
- exe/ragent
|
105
121
|
- lib/ragent.rb
|
122
|
+
- lib/ragent/cli.rb
|
106
123
|
- lib/ragent/command.rb
|
124
|
+
- lib/ragent/command_helpers.rb
|
107
125
|
- lib/ragent/commands.rb
|
126
|
+
- lib/ragent/configurator.rb
|
108
127
|
- lib/ragent/logging.rb
|
109
128
|
- lib/ragent/plugin.rb
|
110
129
|
- lib/ragent/plugins.rb
|
@@ -131,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
131
150
|
version: '0'
|
132
151
|
requirements: []
|
133
152
|
rubyforge_project:
|
134
|
-
rubygems_version: 2.
|
153
|
+
rubygems_version: 2.6.10
|
135
154
|
signing_key:
|
136
155
|
specification_version: 4
|
137
156
|
summary: An agent framework
|