ntl-actor 0.6.2 → 1.0.0.pre1
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/lib/actor.rb +45 -19
- data/lib/actor/actor.rb +12 -132
- data/lib/actor/build.rb +36 -0
- data/lib/actor/controls.rb +7 -7
- data/lib/actor/messages.rb +20 -4
- data/lib/actor/messaging/address.rb +26 -0
- data/lib/actor/messaging/address/controls.rb +11 -0
- data/lib/actor/messaging/address/dependency.rb +13 -0
- data/lib/actor/messaging/address/none.rb +33 -0
- data/lib/actor/messaging/message.rb +39 -1
- data/lib/actor/messaging/message/name.rb +33 -0
- data/lib/actor/messaging/publisher.rb +39 -0
- data/lib/actor/messaging/publisher/assertions.rb +11 -0
- data/lib/actor/messaging/publisher/dependency.rb +13 -0
- data/lib/actor/messaging/publisher/substitute.rb +62 -0
- data/lib/actor/messaging/queue.rb +21 -0
- data/lib/actor/messaging/queue/substitute.rb +53 -0
- data/lib/actor/messaging/reader.rb +32 -0
- data/lib/actor/messaging/reader/assertions.rb +25 -0
- data/lib/actor/messaging/reader/dependency.rb +13 -0
- data/lib/actor/messaging/reader/substitute.rb +31 -0
- data/lib/actor/messaging/writer.rb +28 -0
- data/lib/actor/messaging/writer/dependency.rb +13 -0
- data/lib/actor/messaging/writer/substitute.rb +45 -0
- data/lib/actor/module/dependencies.rb +30 -0
- data/lib/actor/module/dependencies/assertions.rb +23 -0
- data/lib/actor/module/handler.rb +31 -0
- data/lib/actor/module/handler/macro.rb +13 -0
- data/lib/actor/module/handler/method_name.rb +13 -0
- data/lib/actor/module/include_assertions.rb +18 -0
- data/lib/actor/module/run_loop.rb +19 -0
- data/lib/actor/module/start.rb +27 -0
- data/lib/actor/module/suspend_resume.rb +36 -0
- data/lib/actor/module/suspend_resume/assertions.rb +26 -0
- data/lib/actor/module/suspend_resume/configure.rb +13 -0
- data/lib/actor/module/suspend_resume/controls.rb +17 -0
- data/lib/actor/module/suspend_resume/handle.rb +17 -0
- data/lib/actor/module/suspend_resume/initialize.rb +13 -0
- data/lib/actor/start.rb +34 -34
- data/lib/actor/supervisor.rb +60 -71
- data/lib/actor/supervisor/address/get.rb +15 -0
- data/lib/actor/supervisor/address/put.rb +13 -0
- data/lib/actor/supervisor/address/registry.rb +7 -0
- data/lib/actor/supervisor/assertions.rb +20 -0
- metadata +42 -28
- data/lib/actor/address.rb +0 -18
- data/lib/actor/controls/actor.rb +0 -89
- data/lib/actor/controls/address.rb +0 -48
- data/lib/actor/controls/error.rb +0 -11
- data/lib/actor/controls/message.rb +0 -39
- data/lib/actor/controls/message/attribute.rb +0 -17
- data/lib/actor/controls/thread.rb +0 -9
- data/lib/actor/controls/uuid.rb +0 -15
- data/lib/actor/destructure.rb +0 -23
- data/lib/actor/duration.rb +0 -7
- data/lib/actor/future.rb +0 -38
- data/lib/actor/handle_macro.rb +0 -37
- data/lib/actor/messaging/read.rb +0 -54
- data/lib/actor/messaging/read/substitute.rb +0 -33
- data/lib/actor/messaging/write.rb +0 -26
- data/lib/actor/messaging/write/substitute.rb +0 -39
- data/lib/actor/observers.rb +0 -45
- data/lib/actor/router.rb +0 -94
- data/lib/actor/stream.rb +0 -36
- data/lib/actor/substitutes/kernel.rb +0 -23
- data/lib/actor/substitutes/thread.rb +0 -39
- data/lib/actor/substitutes/thread_group.rb +0 -26
@@ -0,0 +1,23 @@
|
|
1
|
+
module Actor
|
2
|
+
module Module
|
3
|
+
module Dependencies
|
4
|
+
module Assertions
|
5
|
+
def dependencies_configured?
|
6
|
+
address_configured? and reader_configured? and writer_configured?
|
7
|
+
end
|
8
|
+
|
9
|
+
def address_configured?
|
10
|
+
address.instance_of? Messaging::Address
|
11
|
+
end
|
12
|
+
|
13
|
+
def reader_configured?
|
14
|
+
reader.instance_of? Messaging::Reader
|
15
|
+
end
|
16
|
+
|
17
|
+
def writer_configured?
|
18
|
+
writer.instance_of? Messaging::Writer
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Actor
|
2
|
+
module Module
|
3
|
+
module Handler
|
4
|
+
def self.included cls
|
5
|
+
cls.class_exec do
|
6
|
+
extend Macro
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def handle message
|
11
|
+
handler_method_name = MethodName.get message
|
12
|
+
|
13
|
+
return unless handler_method_name and respond_to? handler_method_name
|
14
|
+
|
15
|
+
handler_method = method handler_method_name
|
16
|
+
|
17
|
+
if handler_method.arity == 0
|
18
|
+
return_value = handler_method.()
|
19
|
+
else
|
20
|
+
return_value = handler_method.(message)
|
21
|
+
end
|
22
|
+
|
23
|
+
if Messaging::Message === return_value
|
24
|
+
writer.write return_value, address
|
25
|
+
end
|
26
|
+
|
27
|
+
return_value
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Actor
|
2
|
+
module Module
|
3
|
+
module IncludeAssertions
|
4
|
+
def self.call assertions_module, receiver
|
5
|
+
receiver.module_exec do
|
6
|
+
unless const_defined? :Assertions, false
|
7
|
+
receiver_assertions_module = ::Module.new
|
8
|
+
const_set :Assertions, receiver_assertions_module
|
9
|
+
end
|
10
|
+
|
11
|
+
receiver_assertions_module ||= const_get :Assertions
|
12
|
+
|
13
|
+
receiver_assertions_module.include assertions_module
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Actor
|
2
|
+
module Module
|
3
|
+
module RunLoop
|
4
|
+
def run_loop &supplemental_action
|
5
|
+
loop do
|
6
|
+
message = reader.read
|
7
|
+
|
8
|
+
handle message
|
9
|
+
|
10
|
+
supplemental_action.() if supplemental_action
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def handle_stop(_=nil)
|
15
|
+
raise StopIteration
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Actor
|
2
|
+
module Module
|
3
|
+
module Start
|
4
|
+
def start *arguments, include: nil, **keyword_arguments, &block
|
5
|
+
arguments << keyword_arguments if keyword_arguments.any?
|
6
|
+
|
7
|
+
actor, thread = Actor::Start.(self, *arguments, &block)
|
8
|
+
|
9
|
+
address = actor.address
|
10
|
+
|
11
|
+
if include
|
12
|
+
return_values = [address]
|
13
|
+
|
14
|
+
Array(include).each do |label|
|
15
|
+
argument = { :thread => thread, :actor => actor }.fetch label
|
16
|
+
|
17
|
+
return_values << argument
|
18
|
+
end
|
19
|
+
|
20
|
+
return return_values
|
21
|
+
else
|
22
|
+
return address
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Actor
|
2
|
+
module Module
|
3
|
+
module SuspendResume
|
4
|
+
def self.included cls
|
5
|
+
cls.class_exec do
|
6
|
+
prepend Configure
|
7
|
+
prepend Handle
|
8
|
+
prepend Initialize
|
9
|
+
|
10
|
+
IncludeAssertions.(Assertions, self)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :suspended
|
15
|
+
attr_writer :suspend_queue
|
16
|
+
|
17
|
+
def handle_suspend
|
18
|
+
self.suspended = true
|
19
|
+
end
|
20
|
+
|
21
|
+
def handle_resume
|
22
|
+
self.suspended = false
|
23
|
+
|
24
|
+
until suspend_queue.empty?
|
25
|
+
deferred_message = suspend_queue.deq
|
26
|
+
|
27
|
+
writer.write deferred_message, address
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def suspend_queue
|
32
|
+
@suspend_queue ||= Messaging::Queue::Substitute.build
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Actor
|
2
|
+
module Module
|
3
|
+
module SuspendResume
|
4
|
+
module Assertions
|
5
|
+
def message_deferred? message=nil, wait: nil
|
6
|
+
non_block = wait == false
|
7
|
+
|
8
|
+
begin
|
9
|
+
msg = suspend_queue.deq true
|
10
|
+
rescue ThreadError
|
11
|
+
end
|
12
|
+
|
13
|
+
if message.nil?
|
14
|
+
msg ? true : false
|
15
|
+
else
|
16
|
+
msg == message
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def suspended?
|
21
|
+
@suspended == true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Actor
|
2
|
+
module Module
|
3
|
+
module SuspendResume
|
4
|
+
module Controls
|
5
|
+
def suspend!
|
6
|
+
self.suspended = true
|
7
|
+
end
|
8
|
+
|
9
|
+
def defer_message *messages
|
10
|
+
messages.each do |message|
|
11
|
+
suspend_queue.enq message
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Actor
|
2
|
+
module Module
|
3
|
+
module SuspendResume
|
4
|
+
module Handle
|
5
|
+
def handle message
|
6
|
+
self.suspended = false if Messages::Resume === message
|
7
|
+
|
8
|
+
if suspended
|
9
|
+
suspend_queue.enq message, true
|
10
|
+
else
|
11
|
+
super
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/actor/start.rb
CHANGED
@@ -1,57 +1,57 @@
|
|
1
1
|
module Actor
|
2
2
|
class Start
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
def self.build supervisor_address: nil
|
8
|
-
supervisor_address ||= Supervisor.address
|
9
|
-
|
10
|
-
instance = new
|
11
|
-
instance.supervisor_address = supervisor_address
|
12
|
-
instance.thread_class = Thread
|
13
|
-
Messaging::Write.configure instance
|
14
|
-
instance
|
15
|
-
end
|
3
|
+
include Messaging::Writer::Dependency
|
4
|
+
|
5
|
+
attr_reader :actor
|
6
|
+
attr_accessor :supervisor_address
|
16
7
|
|
17
|
-
def
|
18
|
-
|
19
|
-
instance.(actor, address)
|
8
|
+
def initialize actor
|
9
|
+
@actor = actor
|
20
10
|
end
|
21
11
|
|
22
|
-
def call
|
23
|
-
|
12
|
+
def self.call actor_class, *arguments, &block
|
13
|
+
actor = Build.(actor_class, *arguments, &block)
|
24
14
|
|
25
|
-
|
26
|
-
writer.
|
15
|
+
instance = new actor
|
16
|
+
instance.writer = Messaging::Writer.new
|
17
|
+
instance.supervisor_address = Supervisor::Address::Get.()
|
18
|
+
instance.()
|
19
|
+
end
|
27
20
|
|
28
|
-
|
29
|
-
writer.
|
21
|
+
def call
|
22
|
+
writer.write Messages::Start, address
|
23
|
+
|
24
|
+
thread = Thread.new do
|
25
|
+
actor_started
|
30
26
|
|
31
|
-
thread = thread_class.new do
|
32
27
|
begin
|
33
|
-
actor.
|
28
|
+
actor.run_loop
|
29
|
+
actor_stopped
|
34
30
|
rescue => error
|
35
|
-
actor_crashed
|
36
|
-
writer.(actor_crashed, supervisor_address)
|
31
|
+
actor_crashed error
|
37
32
|
end
|
38
33
|
end
|
39
34
|
|
40
|
-
|
35
|
+
return actor, thread
|
36
|
+
end
|
41
37
|
|
42
|
-
|
38
|
+
def actor_crashed error
|
39
|
+
actor_crashed = Messages::ActorCrashed.new error
|
40
|
+
writer.write actor_crashed, supervisor_address
|
43
41
|
end
|
44
42
|
|
45
|
-
def
|
46
|
-
|
43
|
+
def actor_started
|
44
|
+
actor_started = Messages::ActorStarted.new address
|
45
|
+
writer.write actor_started, supervisor_address
|
47
46
|
end
|
48
47
|
|
49
|
-
def
|
50
|
-
|
48
|
+
def actor_stopped
|
49
|
+
actor_stopped = Messages::ActorStopped.new address
|
50
|
+
writer.write actor_stopped, supervisor_address
|
51
51
|
end
|
52
52
|
|
53
|
-
def
|
54
|
-
|
53
|
+
def address
|
54
|
+
actor.address
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
data/lib/actor/supervisor.rb
CHANGED
@@ -1,118 +1,107 @@
|
|
1
1
|
module Actor
|
2
2
|
class Supervisor
|
3
|
-
include
|
3
|
+
include Module::Dependencies
|
4
|
+
include Module::Handler
|
5
|
+
include Module::RunLoop
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
+
include Messaging::Publisher::Dependency
|
8
|
+
|
9
|
+
attr_accessor :actor_count
|
10
|
+
attr_writer :assembly_block
|
7
11
|
attr_accessor :error
|
8
12
|
attr_writer :thread_group
|
9
|
-
attr_writer :router_address
|
10
13
|
|
11
|
-
def initialize
|
12
|
-
@
|
14
|
+
def initialize
|
15
|
+
@actor_count = 0
|
13
16
|
end
|
14
17
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
_, thread = start include: %i(thread), &assembly
|
18
|
+
def self.build &assembly_block
|
19
|
+
instance = new
|
20
|
+
instance.assembly_block = assembly_block
|
21
|
+
instance.configure
|
22
|
+
instance
|
23
|
+
end
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
+
def self.start &assembly_block
|
26
|
+
thread = Thread.new do
|
27
|
+
thread_group = Thread.current.group
|
25
28
|
|
26
|
-
|
27
|
-
instance = new &assembly
|
28
|
-
instance.configure
|
29
|
-
instance
|
30
|
-
end
|
29
|
+
prior_thread_count = thread_group.list.count
|
31
30
|
|
32
|
-
|
33
|
-
instance = build &assembly
|
31
|
+
instance = build &assembly_block
|
34
32
|
|
35
|
-
|
36
|
-
instance.writer.(start, address)
|
33
|
+
thread_count = thread_group.list.count
|
37
34
|
|
38
|
-
|
39
|
-
|
35
|
+
unless thread_count > prior_thread_count
|
36
|
+
raise NoActorsStarted, "Assembly block must start at least one actor"
|
40
37
|
end
|
41
38
|
|
42
|
-
|
43
|
-
|
44
|
-
Destructure.(address, include, { :thread => thread, :actor => instance })
|
39
|
+
instance.run_loop
|
45
40
|
end
|
41
|
+
|
42
|
+
thread.join
|
46
43
|
end
|
47
44
|
|
48
|
-
|
49
|
-
thread_group
|
50
|
-
thread_group.enclose
|
45
|
+
def configure
|
46
|
+
self.thread_group = Thread.current.group
|
51
47
|
|
52
|
-
|
48
|
+
Address::Put.(address)
|
53
49
|
|
54
|
-
|
55
|
-
end
|
50
|
+
assembly_block.(self)
|
56
51
|
|
57
|
-
|
58
|
-
|
59
|
-
raise error if error
|
52
|
+
self.publisher = Messaging::Publisher.build
|
53
|
+
end
|
60
54
|
|
61
|
-
|
62
|
-
|
63
|
-
sleep Duration.millisecond
|
55
|
+
handle Messages::ActorStarted do |message|
|
56
|
+
publisher.register message.address
|
64
57
|
|
65
|
-
|
66
|
-
end
|
58
|
+
self.actor_count += 1
|
67
59
|
end
|
68
60
|
|
69
|
-
handle
|
70
|
-
|
71
|
-
output_address = message.actor_address
|
61
|
+
handle Messages::ActorStopped do |message|
|
62
|
+
publisher.unregister message.address
|
72
63
|
|
73
|
-
|
64
|
+
self.actor_count -= 1
|
74
65
|
|
75
|
-
|
66
|
+
if actor_count.zero?
|
67
|
+
Messages::Stop
|
68
|
+
end
|
76
69
|
end
|
77
70
|
|
78
|
-
handle
|
71
|
+
handle Messages::ActorCrashed do |message|
|
79
72
|
self.error ||= message.error
|
80
73
|
|
81
|
-
|
82
|
-
end
|
83
|
-
|
84
|
-
handle :shutdown do
|
85
|
-
stop = Messages::Stop.new
|
74
|
+
self.actor_count -= 1
|
86
75
|
|
87
|
-
|
88
|
-
|
76
|
+
Messages::Shutdown
|
77
|
+
end
|
89
78
|
|
90
|
-
|
79
|
+
handle Messages::Shutdown do
|
80
|
+
publisher.publish Messages::Stop
|
91
81
|
end
|
92
82
|
|
93
|
-
|
94
|
-
|
95
|
-
list.delete Thread.current
|
96
|
-
list
|
83
|
+
handle Messages::Suspend do |message|
|
84
|
+
publisher.publish message
|
97
85
|
end
|
98
86
|
|
99
|
-
|
100
|
-
|
101
|
-
self.router_address = Router.start
|
102
|
-
self.thread_group = ThreadGroup.new
|
103
|
-
self.address = self.class.address
|
87
|
+
handle Messages::Resume do |message|
|
88
|
+
publisher.publish message
|
104
89
|
end
|
105
90
|
|
106
|
-
|
107
|
-
|
91
|
+
handle Messages::Stop do |stop|
|
92
|
+
raise error if error
|
93
|
+
|
94
|
+
super stop
|
108
95
|
end
|
109
96
|
|
110
|
-
def
|
111
|
-
@
|
97
|
+
def assembly_block
|
98
|
+
@assembly_block ||= proc { }
|
112
99
|
end
|
113
100
|
|
114
101
|
def thread_group
|
115
|
-
@thread_group ||=
|
102
|
+
@thread_group ||= ThreadGroup::Default
|
116
103
|
end
|
104
|
+
|
105
|
+
NoActorsStarted = Class.new StandardError
|
117
106
|
end
|
118
107
|
end
|