ntl-actor 0.4.0.pre1 → 0.4.0.pre3

Sign up to get free protection for your applications and to get access to all the features.
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