ntl-actor 0.4.0.pre1 → 0.4.0.pre3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8390670d6cdb63d966590bc7456a583e424b21aa
4
- data.tar.gz: 71bc7ef3d159c05ada78869eff267f6e683ff7a9
3
+ metadata.gz: dbe44cb51a0d65ba55a27567bf83be3730356148
4
+ data.tar.gz: a8b2ce1e78a1e2ed0ceaf03033143724708c985d
5
5
  SHA512:
6
- metadata.gz: d9bc1d1dd129fa2d4275a3bb57a051826c7808f6d426c68cde2a3e336f1d70301ac2456729516dc7203e6a30a7ac8c17523e27d453270fd3f87867fca4acbcbf
7
- data.tar.gz: 7164e075114eec599f0233c386f6bf77335e03edd140e51d28159d379e8b5280fc5181ffdce386f80ce6b6a37cb89076bbecedeee081a9fd4b84f72d1be879da
6
+ metadata.gz: 5e3bfa5de54e9b4100477c9ec769547aa10b075e527cef2f0a1af5a921e99d25ed13e286e5eb8ba981ea237c4132fd1478432f3cfe265ff672627c69b9405121
7
+ data.tar.gz: 93cfaa302f392e08de33928dbde3fb32713889e5b855f17e6e59fd1581c595c4d5acc39a85485059d95fe38b2cf3a52fd026d6503e9f5f8e1d5b7343775bf970
data/lib/actor.rb CHANGED
@@ -21,6 +21,7 @@ require 'actor/messages'
21
21
 
22
22
  require 'actor/module/build'
23
23
  require 'actor/module/handle_macro'
24
+ require 'actor/module/observers'
24
25
  require 'actor/module/start'
25
26
  require 'actor/module'
26
27
 
@@ -28,5 +29,6 @@ require 'actor/start'
28
29
 
29
30
  require 'actor/actor'
30
31
 
32
+ require 'actor/future'
31
33
  require 'actor/router'
32
34
  require 'actor/supervisor'
data/lib/actor/address.rb CHANGED
@@ -13,6 +13,6 @@ module Actor
13
13
  class Address
14
14
  NoneClass = Class.new Address
15
15
 
16
- None = NoneClass.build Stream::Null
16
+ None = NoneClass.new Stream::Null, 'no-stream'
17
17
  end
18
18
  end
@@ -32,6 +32,9 @@ module Actor
32
32
  Message.example
33
33
  end
34
34
  end
35
+
36
+ handle Message::Example do
37
+ end
35
38
  end
36
39
 
37
40
  class Stops
@@ -0,0 +1,38 @@
1
+ module Actor
2
+ class Future
3
+ attr_reader :reader
4
+ attr_accessor :message
5
+
6
+ def initialize reader
7
+ @reader = reader
8
+ end
9
+
10
+ def self.build &block
11
+ address = Address.build
12
+ reader = Messaging::Read.build address
13
+
14
+ instance = new reader
15
+
16
+ block.(address)
17
+
18
+ instance
19
+ end
20
+
21
+ def self.get wait: nil, &block
22
+ instance = build &block
23
+ instance.get wait: wait
24
+ end
25
+
26
+ def get wait: nil
27
+ return message unless message.nil?
28
+
29
+ self.message = reader.(wait: wait)
30
+ end
31
+
32
+ def ready?
33
+ get
34
+
35
+ message ? true : false
36
+ end
37
+ end
38
+ end
@@ -45,6 +45,10 @@ module Actor
45
45
  end
46
46
  end
47
47
  end
48
+
49
+ def messages_available?
50
+ not queue.empty?
51
+ end
48
52
  end
49
53
  end
50
54
  end
@@ -12,6 +12,10 @@ module Actor
12
12
  message
13
13
  end
14
14
 
15
+ def messages_available?
16
+ messages.any?
17
+ end
18
+
15
19
  def add_message message
16
20
  messages << message
17
21
  end
data/lib/actor/module.rb CHANGED
@@ -5,9 +5,12 @@ module Actor
5
5
  extend Build
6
6
  extend HandleMacro
7
7
  extend Start
8
+
9
+ include Observers
8
10
  end
9
11
  end
10
12
 
13
+ attr_writer :address
11
14
  attr_writer :reader
12
15
  attr_writer :writer
13
16
 
@@ -24,10 +27,14 @@ module Actor
24
27
  return if method.nil?
25
28
 
26
29
  if method.arity == 0
27
- method.()
30
+ return_value = method.()
28
31
  else
29
- method.(message)
32
+ return_value = method.(message)
30
33
  end
34
+
35
+ notify_observers message
36
+
37
+ return_value
31
38
  end
32
39
 
33
40
  def handle_stop
@@ -52,16 +59,23 @@ module Actor
52
59
 
53
60
  continuation_message = handle message
54
61
 
55
- if continuation_message.is_a? Messaging::Message
62
+ if handle? continuation_message
56
63
  continuations << continuation_message
57
64
  end
58
65
  end
59
66
 
60
67
  def run_loop
61
- loop do self.next end
68
+ loop do
69
+ self.next
70
+ Thread.pass
71
+ end
62
72
  end
63
73
  alias_method :start, :run_loop
64
74
 
75
+ def address
76
+ @address ||= Address::None
77
+ end
78
+
65
79
  def reader
66
80
  @reader ||= Messaging::Read::Substitute.new
67
81
  end
@@ -8,6 +8,7 @@ module Actor
8
8
  instance = new *positional_arguments, **keyword_arguments, &block
9
9
  end
10
10
 
11
+ instance.address = address
11
12
  instance.reader = Messaging::Read.build address
12
13
  instance.writer = Messaging::Write.new
13
14
 
@@ -0,0 +1,47 @@
1
+ module Actor
2
+ module Module
3
+ module Observers
4
+ def observe message_pattern, &callback
5
+ handler_method = HandleMacro::MethodName.get message_pattern
6
+
7
+ observer_id = callback.object_id
8
+
9
+ record = Observer.new observer_id, handler_method, callback
10
+
11
+ add_observer record
12
+ end
13
+
14
+ def add_observer record
15
+ observers = observer_registry[record.handler_method]
16
+
17
+ observers[record.observer_id] = record
18
+ end
19
+
20
+ def notify_observers message
21
+ handler_method = HandleMacro::MethodName.get message
22
+
23
+ observers = observer_registry[handler_method]
24
+
25
+ observers.each_value.map do |record|
26
+ callback = record.callback
27
+
28
+ callback.(message)
29
+ end
30
+ end
31
+
32
+ def remove_observer record
33
+ observers = observer_registry[record.handler_method]
34
+
35
+ observers.delete record.observer_id
36
+ end
37
+
38
+ def observer_registry
39
+ @observer_registry ||= Hash.new do |hash, handler_method|
40
+ hash[handler_method] = {}
41
+ end
42
+ end
43
+
44
+ Observer = Struct.new :observer_id, :handler_method, :callback
45
+ end
46
+ end
47
+ end
data/lib/actor/router.rb CHANGED
@@ -16,19 +16,7 @@ module Actor
16
16
  end
17
17
 
18
18
  handle :continue do
19
- routed_messages = false
20
-
21
- routes.each do |input_reader, outputs|
22
- msg = input_reader.(wait: false)
23
-
24
- next unless msg
25
-
26
- routed_messages = true
27
-
28
- outputs.each do |output|
29
- writer.(msg, output)
30
- end
31
- end
19
+ routed_messages = route_messages
32
20
 
33
21
  unless routed_messages
34
22
  kernel.sleep Duration.millisecond
@@ -51,6 +39,15 @@ module Actor
51
39
  remove reader, output_address
52
40
  end
53
41
 
42
+ handle :stop do
43
+ if routes.any? { |reader, _| reader.messages_available? }
44
+ route_messages
45
+ :stop
46
+ else
47
+ super()
48
+ end
49
+ end
50
+
54
51
  def add reader, output_address
55
52
  routes[reader] << output_address
56
53
  end
@@ -59,6 +56,24 @@ module Actor
59
56
  routes[reader].delete output_address
60
57
  end
61
58
 
59
+ def route_messages
60
+ routed_messages = false
61
+
62
+ routes.each do |input_reader, outputs|
63
+ msg = input_reader.(wait: false)
64
+
65
+ next unless msg
66
+
67
+ routed_messages = true
68
+
69
+ outputs.each do |output|
70
+ writer.(msg, output)
71
+ end
72
+ end
73
+
74
+ routed_messages
75
+ end
76
+
62
77
  def configure
63
78
  self.kernel = Kernel
64
79
  end
data/lib/actor/start.rb CHANGED
@@ -1,13 +1,15 @@
1
1
  module Actor
2
2
  class Start
3
3
  attr_writer :supervisor_address
4
- attr_writer :thread
4
+ attr_writer :thread_class
5
5
  attr_writer :writer
6
6
 
7
7
  def self.build supervisor_address: nil
8
+ supervisor_address ||= Supervisor.address
9
+
8
10
  instance = new
9
11
  instance.supervisor_address = supervisor_address
10
- instance.thread = Thread
12
+ instance.thread_class = Thread
11
13
  Messaging::Write.configure instance
12
14
  instance
13
15
  end
@@ -26,17 +28,21 @@ module Actor
26
28
  actor_started = Messages::ActorStarted.new address
27
29
  writer.(actor_started, supervisor_address)
28
30
 
29
- self.thread.new do
31
+ thread = thread_class.new do
30
32
  actor.start
31
33
  end
34
+
35
+ thread.name = actor.class.name
36
+
37
+ thread
32
38
  end
33
39
 
34
40
  def supervisor_address
35
41
  @supervisor_address ||= Address::None
36
42
  end
37
43
 
38
- def thread
39
- @thread ||= Substitutes::Thread
44
+ def thread_class
45
+ @thread_class ||= Substitutes::Thread
40
46
  end
41
47
 
42
48
  def writer
@@ -2,20 +2,44 @@ module Actor
2
2
  class Supervisor
3
3
  include Actor
4
4
 
5
+ attr_reader :assembly
5
6
  attr_writer :broadcast_address
6
7
  attr_accessor :error
7
8
  attr_writer :thread_group
8
9
  attr_writer :router_address
9
10
 
11
+ def initialize &assembly
12
+ @assembly = assembly
13
+ end
14
+
15
+ def self.run &block
16
+ self.address, thread = start include: %i(thread), &block
17
+
18
+ thread.join
19
+ end
20
+
21
+ def self.address
22
+ @address ||= Address::None
23
+ end
24
+
25
+ def self.address= address
26
+ @address = address
27
+ end
28
+
10
29
  handle :start do
30
+ thread_group.add Thread.current
31
+ thread_group.enclose
32
+
33
+ assembly.(self) if assembly
34
+
11
35
  :continue
12
36
  end
13
37
 
14
- handle :continue do |message|
38
+ handle :continue do
15
39
  if actor_threads.empty?
16
40
  :stop
17
41
  else
18
- message
42
+ :continue
19
43
  end
20
44
  end
21
45
 
@@ -50,12 +74,9 @@ module Actor
50
74
  end
51
75
 
52
76
  def configure
53
- thread_group = ThreadGroup.new
54
- thread_group.add Thread.current
55
-
56
77
  self.broadcast_address = Address.build
57
78
  self.router_address = Router.start
58
- self.thread_group = thread_group
79
+ self.thread_group = ThreadGroup.new
59
80
  end
60
81
 
61
82
  def broadcast_address
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ntl-actor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0.pre1
4
+ version: 0.4.0.pre3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Ladd
@@ -30,6 +30,7 @@ files:
30
30
  - lib/actor/controls/uuid.rb
31
31
  - lib/actor/destructure.rb
32
32
  - lib/actor/duration.rb
33
+ - lib/actor/future.rb
33
34
  - lib/actor/messages.rb
34
35
  - lib/actor/messaging/message.rb
35
36
  - lib/actor/messaging/read.rb
@@ -39,6 +40,7 @@ files:
39
40
  - lib/actor/module.rb
40
41
  - lib/actor/module/build.rb
41
42
  - lib/actor/module/handle_macro.rb
43
+ - lib/actor/module/observers.rb
42
44
  - lib/actor/module/start.rb
43
45
  - lib/actor/router.rb
44
46
  - lib/actor/start.rb