evt-component_host 0.1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/component_host.rb +14 -0
- data/lib/component_host/component_host.rb +13 -0
- data/lib/component_host/controls.rb +7 -0
- data/lib/component_host/controls/error.rb +11 -0
- data/lib/component_host/controls/process_name.rb +9 -0
- data/lib/component_host/controls/start_component.rb +23 -0
- data/lib/component_host/controls/start_component/actor_crashes.rb +27 -0
- data/lib/component_host/controls/start_component/raises_error.rb +15 -0
- data/lib/component_host/controls/start_component/runs_continuously.rb +40 -0
- data/lib/component_host/controls/start_component/stops_immediately.rb +19 -0
- data/lib/component_host/host.rb +115 -0
- data/lib/component_host/log.rb +8 -0
- data/lib/component_host/signal.rb +53 -0
- data/lib/component_host/supervisor_observers/log.rb +22 -0
- data/lib/component_host/supervisor_observers/record_errors.rb +23 -0
- metadata +142 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2d2bd4f87854d29af6a297eeff88d89f10eb1280
|
4
|
+
data.tar.gz: 9a2ad4c114ff8ad79309617813491a512b10d97c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 58f87556a16591d3f490c81f83020278b152096c6cc98d8439aa5ea258b2fee9d3021187d7de04a45f6f19db17f5460d7b86af42bdddb516ce9c439c1c8028f0
|
7
|
+
data.tar.gz: e39f8800e022ebdd72a002cad48f864ca3f8e62f60fe72daed997f60951e8ba7fe963e4ebcacb868d8cb2bfb41cc10b34732a81e911ea75a31c7f376042313e9
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'actor'
|
2
|
+
require 'async_invocation'
|
3
|
+
require 'casing'
|
4
|
+
require 'log'
|
5
|
+
require 'virtual'
|
6
|
+
|
7
|
+
require 'component_host/log'
|
8
|
+
require 'component_host/signal'
|
9
|
+
|
10
|
+
require 'component_host/host'
|
11
|
+
require 'component_host/supervisor_observers/log'
|
12
|
+
require 'component_host/supervisor_observers/record_errors'
|
13
|
+
|
14
|
+
require 'component_host/component_host'
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module ComponentHost
|
2
|
+
def self.start(component_name, &block)
|
3
|
+
logger = ::Log.get self
|
4
|
+
|
5
|
+
host = Host.build
|
6
|
+
|
7
|
+
host.instance_exec host, &block
|
8
|
+
|
9
|
+
host.start do
|
10
|
+
logger.info "Started component: #{component_name} (ProcessID: #{::Process.pid})"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
require 'component_host/controls/error'
|
2
|
+
require 'component_host/controls/process_name'
|
3
|
+
require 'component_host/controls/start_component'
|
4
|
+
require 'component_host/controls/start_component/actor_crashes'
|
5
|
+
require 'component_host/controls/start_component/raises_error'
|
6
|
+
require 'component_host/controls/start_component/runs_continuously'
|
7
|
+
require 'component_host/controls/start_component/stops_immediately'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ComponentHost
|
2
|
+
module Controls
|
3
|
+
module StartComponent
|
4
|
+
def self.example
|
5
|
+
Example.new
|
6
|
+
end
|
7
|
+
|
8
|
+
class Example
|
9
|
+
attr_accessor :executed
|
10
|
+
|
11
|
+
def call
|
12
|
+
self.executed = true
|
13
|
+
end
|
14
|
+
|
15
|
+
module Assertions
|
16
|
+
def executed?
|
17
|
+
executed ? true : false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module ComponentHost
|
2
|
+
module Controls
|
3
|
+
module StartComponent
|
4
|
+
module ActorCrashes
|
5
|
+
def self.call
|
6
|
+
Actor.start
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.error
|
10
|
+
@error ||= Error.example
|
11
|
+
end
|
12
|
+
|
13
|
+
class Actor
|
14
|
+
include ::Actor
|
15
|
+
|
16
|
+
handle :start do
|
17
|
+
raise error
|
18
|
+
end
|
19
|
+
|
20
|
+
def error
|
21
|
+
ActorCrashes.error
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module ComponentHost
|
2
|
+
module Controls
|
3
|
+
module StartComponent
|
4
|
+
module RunsContinuously
|
5
|
+
def self.call
|
6
|
+
Actor.start
|
7
|
+
end
|
8
|
+
|
9
|
+
class Actor
|
10
|
+
include ::Actor
|
11
|
+
include ::Log::Dependency
|
12
|
+
|
13
|
+
attr_writer :counter
|
14
|
+
|
15
|
+
handle :start do
|
16
|
+
:print_heartbeat
|
17
|
+
end
|
18
|
+
|
19
|
+
handle :print_heartbeat do
|
20
|
+
logger.info "Heartbeat (Counter: #{counter})"
|
21
|
+
|
22
|
+
:next
|
23
|
+
end
|
24
|
+
|
25
|
+
handle :next do
|
26
|
+
self.counter += 1
|
27
|
+
|
28
|
+
sleep 1
|
29
|
+
|
30
|
+
:print_heartbeat
|
31
|
+
end
|
32
|
+
|
33
|
+
def counter
|
34
|
+
@counter ||= 0
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module ComponentHost
|
2
|
+
class Host
|
3
|
+
include ::Log::Dependency
|
4
|
+
|
5
|
+
dependency :signal, Signal
|
6
|
+
dependency :send, Actor::Messaging::Send
|
7
|
+
|
8
|
+
def self.build
|
9
|
+
instance = new
|
10
|
+
Signal.configure instance
|
11
|
+
instance.send = Actor::Messaging::Send
|
12
|
+
instance
|
13
|
+
end
|
14
|
+
|
15
|
+
def register(start_proc, name=nil, &block)
|
16
|
+
start_proc ||= proc { yield }
|
17
|
+
|
18
|
+
logger.trace { "Registering component (StartProcedure: #{start_proc}, Name: #{name || '(none)'})" }
|
19
|
+
|
20
|
+
component = Component.new start_proc, name
|
21
|
+
|
22
|
+
components << component
|
23
|
+
|
24
|
+
logger.debug { "Component registered (StartProcedure: #{start_proc}, Name: #{name || '(none)'})" }
|
25
|
+
|
26
|
+
component
|
27
|
+
end
|
28
|
+
|
29
|
+
def record_error(&block)
|
30
|
+
record_errors_observer.record_error_proc = block
|
31
|
+
end
|
32
|
+
|
33
|
+
def start(&block)
|
34
|
+
started_components = []
|
35
|
+
|
36
|
+
Actor::Supervisor.start do |supervisor|
|
37
|
+
supervisor.add_observer record_errors_observer
|
38
|
+
|
39
|
+
supervisor.add_observer log_observer
|
40
|
+
|
41
|
+
signal.trap 'TSTP' do
|
42
|
+
message = Actor::Messages::Suspend
|
43
|
+
|
44
|
+
send.(message, supervisor.address)
|
45
|
+
|
46
|
+
logger.info { "Handled TSTP signal (MessageName: #{message.message_name}, SupervisorAddress: #{supervisor.address.id})" }
|
47
|
+
end
|
48
|
+
|
49
|
+
signal.trap 'CONT' do
|
50
|
+
message = Actor::Messages::Resume
|
51
|
+
|
52
|
+
send.(message, supervisor.address)
|
53
|
+
|
54
|
+
logger.info { "Handled CONT signal (MessageName: #{message.message_name}, SupervisorAddress: #{supervisor.address.id})" }
|
55
|
+
end
|
56
|
+
|
57
|
+
signal.trap 'INT' do
|
58
|
+
message = Actor::Messages::Shutdown
|
59
|
+
|
60
|
+
send.(message, supervisor.address)
|
61
|
+
|
62
|
+
logger.info { "Handled INT signal (MessageName: #{message.message_name}, SupervisorAddress: #{supervisor.address.id})" }
|
63
|
+
end
|
64
|
+
|
65
|
+
start_components do |component|
|
66
|
+
started_components << component
|
67
|
+
end
|
68
|
+
|
69
|
+
block.(supervisor) if block
|
70
|
+
end
|
71
|
+
|
72
|
+
started_components
|
73
|
+
end
|
74
|
+
|
75
|
+
def start_components(&block)
|
76
|
+
components.each do |component|
|
77
|
+
component.start
|
78
|
+
|
79
|
+
block.(component) if block
|
80
|
+
end
|
81
|
+
|
82
|
+
rescue => error
|
83
|
+
record_errors_observer.(error)
|
84
|
+
raise error
|
85
|
+
end
|
86
|
+
|
87
|
+
def record_errors_observer
|
88
|
+
@record_errors_observer ||= SupervisorObservers::RecordErrors.new
|
89
|
+
end
|
90
|
+
|
91
|
+
def log_observer
|
92
|
+
@log_observer ||= SupervisorObservers::Log.new
|
93
|
+
end
|
94
|
+
|
95
|
+
def components
|
96
|
+
@components ||= []
|
97
|
+
end
|
98
|
+
|
99
|
+
Component = Struct.new :start_proc, :name do
|
100
|
+
def start
|
101
|
+
start_proc.()
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
module Assertions
|
106
|
+
def registered?(&block)
|
107
|
+
block ||= proc { true }
|
108
|
+
|
109
|
+
components.any? do |component|
|
110
|
+
block.(component.start_proc, component.name)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module ComponentHost
|
2
|
+
module Signal
|
3
|
+
def self.configure(receiver, attr_name: nil)
|
4
|
+
attr_name ||= :signal
|
5
|
+
|
6
|
+
receiver.public_send "#{attr_name}=", ::Signal
|
7
|
+
end
|
8
|
+
|
9
|
+
module Substitute
|
10
|
+
def self.build
|
11
|
+
Signal.new
|
12
|
+
end
|
13
|
+
|
14
|
+
class Signal
|
15
|
+
def trap(signal, &handler)
|
16
|
+
handlers[signal] = handler
|
17
|
+
end
|
18
|
+
|
19
|
+
def simulate_signal(signal)
|
20
|
+
handler = handlers[signal]
|
21
|
+
|
22
|
+
return if handler.nil?
|
23
|
+
|
24
|
+
handler.()
|
25
|
+
|
26
|
+
record = Record.new signal
|
27
|
+
records << record
|
28
|
+
record
|
29
|
+
end
|
30
|
+
|
31
|
+
def handlers
|
32
|
+
@handlers ||= {}
|
33
|
+
end
|
34
|
+
|
35
|
+
def records
|
36
|
+
@records ||= []
|
37
|
+
end
|
38
|
+
|
39
|
+
Record = Struct.new :signal
|
40
|
+
|
41
|
+
module Assertions
|
42
|
+
def trapped?(signal=nil)
|
43
|
+
if signal.nil?
|
44
|
+
records.any?
|
45
|
+
else
|
46
|
+
records.any? { |record| record.signal == signal }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ComponentHost
|
2
|
+
module SupervisorObservers
|
3
|
+
class Log
|
4
|
+
include Actor::Supervisor::Observer
|
5
|
+
include ComponentHost::Log::Dependency
|
6
|
+
|
7
|
+
handle Actor::Messages::ActorStarted do |msg|
|
8
|
+
logger.debug "Actor started (Address: #{msg.address.id}, Actor: #{msg.actor.digest})"
|
9
|
+
end
|
10
|
+
|
11
|
+
handle Actor::Messages::ActorStopped do |msg|
|
12
|
+
logger.debug "Actor stopped (Address: #{msg.address.id}, Actor: #{msg.actor.digest})"
|
13
|
+
end
|
14
|
+
|
15
|
+
handle Actor::Messages::ActorCrashed do |msg|
|
16
|
+
error = msg.error
|
17
|
+
|
18
|
+
logger.error "Error raised (ErrorClass: #{error.class.name}, Actor: #{msg.actor.digest}, Message: #{error.message.inspect})"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ComponentHost
|
2
|
+
module SupervisorObservers
|
3
|
+
class RecordErrors
|
4
|
+
include Actor::Supervisor::Observer
|
5
|
+
|
6
|
+
attr_writer :record_error_proc
|
7
|
+
|
8
|
+
handle Actor::Messages::ActorCrashed do |msg|
|
9
|
+
error = msg.error
|
10
|
+
|
11
|
+
self.(error)
|
12
|
+
end
|
13
|
+
|
14
|
+
def call error
|
15
|
+
record_error_proc.(error)
|
16
|
+
end
|
17
|
+
|
18
|
+
def record_error_proc
|
19
|
+
@record_error_proc ||= proc { }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: evt-component_host
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- The Eventide Project
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-05-31 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ntl-actor
|
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: evt-async_invocation
|
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: evt-casing
|
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: evt-log
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: evt-virtual
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: test_bench
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: " "
|
98
|
+
email: opensource@eventide-project.org
|
99
|
+
executables: []
|
100
|
+
extensions: []
|
101
|
+
extra_rdoc_files: []
|
102
|
+
files:
|
103
|
+
- lib/component_host.rb
|
104
|
+
- lib/component_host/component_host.rb
|
105
|
+
- lib/component_host/controls.rb
|
106
|
+
- lib/component_host/controls/error.rb
|
107
|
+
- lib/component_host/controls/process_name.rb
|
108
|
+
- lib/component_host/controls/start_component.rb
|
109
|
+
- lib/component_host/controls/start_component/actor_crashes.rb
|
110
|
+
- lib/component_host/controls/start_component/raises_error.rb
|
111
|
+
- lib/component_host/controls/start_component/runs_continuously.rb
|
112
|
+
- lib/component_host/controls/start_component/stops_immediately.rb
|
113
|
+
- lib/component_host/host.rb
|
114
|
+
- lib/component_host/log.rb
|
115
|
+
- lib/component_host/signal.rb
|
116
|
+
- lib/component_host/supervisor_observers/log.rb
|
117
|
+
- lib/component_host/supervisor_observers/record_errors.rb
|
118
|
+
homepage: https://github.com/eventide-project/component-host
|
119
|
+
licenses:
|
120
|
+
- MIT
|
121
|
+
metadata: {}
|
122
|
+
post_install_message:
|
123
|
+
rdoc_options: []
|
124
|
+
require_paths:
|
125
|
+
- lib
|
126
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '2.4'
|
131
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
requirements: []
|
137
|
+
rubyforge_project:
|
138
|
+
rubygems_version: 2.6.11
|
139
|
+
signing_key:
|
140
|
+
specification_version: 4
|
141
|
+
summary: Host components inside a single physical process
|
142
|
+
test_files: []
|