ntl-actor 0.3.1 → 0.4.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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/lib/actor/actor.rb +7 -147
  3. data/lib/actor/address.rb +18 -0
  4. data/lib/actor/controls/actor.rb +27 -40
  5. data/lib/actor/controls/address.rb +48 -0
  6. data/lib/actor/controls/error.rb +17 -0
  7. data/lib/actor/controls/message/attribute.rb +17 -0
  8. data/lib/actor/controls/message.rb +23 -1
  9. data/lib/actor/controls/thread.rb +9 -0
  10. data/lib/actor/controls/uuid.rb +15 -0
  11. data/lib/actor/controls.rb +6 -10
  12. data/lib/actor/destructure.rb +23 -0
  13. data/lib/actor/{time_unit.rb → duration.rb} +1 -1
  14. data/lib/actor/messages.rb +15 -0
  15. data/lib/actor/messaging/message.rb +5 -0
  16. data/lib/actor/messaging/{writer → read}/substitute.rb +13 -10
  17. data/lib/actor/messaging/read.rb +50 -0
  18. data/lib/actor/messaging/write/substitute.rb +39 -0
  19. data/lib/actor/messaging/write.rb +26 -0
  20. data/lib/actor/module/build.rb +20 -0
  21. data/lib/actor/module/handle_macro.rb +39 -0
  22. data/lib/actor/module/start.rb +19 -0
  23. data/lib/actor/module.rb +73 -0
  24. data/lib/actor/router.rb +79 -0
  25. data/lib/actor/start.rb +46 -0
  26. data/lib/actor/stream.rb +36 -0
  27. data/lib/actor/substitutes/kernel.rb +23 -0
  28. data/lib/actor/substitutes/thread.rb +39 -0
  29. data/lib/actor/substitutes/thread_group.rb +26 -0
  30. data/lib/actor/supervisor.rb +46 -52
  31. data/lib/actor.rb +22 -14
  32. metadata +29 -29
  33. data/lib/actor/controls/statistics/elapsed_time/average.rb +0 -21
  34. data/lib/actor/controls/statistics/elapsed_time/maximum.rb +0 -21
  35. data/lib/actor/controls/statistics/elapsed_time/minimum.rb +0 -21
  36. data/lib/actor/controls/statistics/elapsed_time/standard_deviation.rb +0 -38
  37. data/lib/actor/controls/statistics/elapsed_time.rb +0 -15
  38. data/lib/actor/controls/statistics/timer.rb +0 -19
  39. data/lib/actor/controls/statistics.rb +0 -21
  40. data/lib/actor/controls/time/clock.rb +0 -31
  41. data/lib/actor/controls/time.rb +0 -24
  42. data/lib/actor/message.rb +0 -23
  43. data/lib/actor/messaging/address.rb +0 -40
  44. data/lib/actor/messaging/reader/substitute.rb +0 -40
  45. data/lib/actor/messaging/reader.rb +0 -31
  46. data/lib/actor/messaging/writer.rb +0 -26
  47. data/lib/actor/queue/assertions.rb +0 -13
  48. data/lib/actor/queue/reader.rb +0 -57
  49. data/lib/actor/queue.rb +0 -122
  50. data/lib/actor/statistics/copy.rb +0 -19
  51. data/lib/actor/statistics/timer.rb +0 -26
  52. data/lib/actor/statistics.rb +0 -75
  53. data/lib/actor/test_fixtures/parallel_iteration.rb +0 -143
  54. data/lib/actor/test_fixtures/sample_actor_status.rb +0 -45
  55. data/lib/actor/test_fixtures.rb +0 -4
@@ -1,21 +0,0 @@
1
- module Actor
2
- module Controls
3
- module Statistics
4
- module ElapsedTime
5
- module Maximum
6
- def self.configure_timer receiver
7
- ElapsedTime.configure_timer receiver, elapsed_times
8
- end
9
-
10
- def self.elapsed_times
11
- [1, 11, 111]
12
- end
13
-
14
- def self.value
15
- 111
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,21 +0,0 @@
1
- module Actor
2
- module Controls
3
- module Statistics
4
- module ElapsedTime
5
- module Minimum
6
- def self.configure_timer receiver
7
- ElapsedTime.configure_timer receiver, elapsed_times
8
- end
9
-
10
- def self.elapsed_times
11
- [111, 11, 1]
12
- end
13
-
14
- def self.value
15
- 1
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,38 +0,0 @@
1
- # See https://rosettacode.org/wiki/Standard_deviation
2
- module Actor
3
- module Controls
4
- module Statistics
5
- module ElapsedTime
6
- module StandardDeviation
7
- def self.configure_timer receiver
8
- ElapsedTime.configure_timer receiver, elapsed_times
9
- end
10
-
11
- def self.elapsed_times
12
- [2, 4, 4, 4, 5, 5, 7, 9]
13
- end
14
-
15
- def self.average
16
- 5
17
- end
18
-
19
- def self.maximum
20
- 7
21
- end
22
-
23
- def self.minimum
24
- 3
25
- end
26
-
27
- def self.percent
28
- 40.0
29
- end
30
-
31
- def self.value
32
- 2
33
- end
34
- end
35
- end
36
- end
37
- end
38
- end
@@ -1,15 +0,0 @@
1
- module Actor
2
- module Controls
3
- module Statistics
4
- module ElapsedTime
5
- def self.configure_timer receiver, elapsed_times
6
- timer = Timer.example elapsed_times
7
-
8
- receiver.timer = timer
9
-
10
- elapsed_times.count
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -1,19 +0,0 @@
1
- module Actor
2
- module Controls
3
- module Statistics
4
- module Timer
5
- def self.example elapsed_times=nil
6
- elapsed_times ||= [Controls::Time::ElapsedTime.example]
7
-
8
- steps = elapsed_times.flat_map do |elapsed_time|
9
- [elapsed_time, 0]
10
- end
11
-
12
- timer = ::Actor::Statistics::Timer.new
13
- timer.clock = Time::Clock.build steps
14
- timer
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,21 +0,0 @@
1
- module Actor
2
- module Controls
3
- module Statistics
4
- def self.example executions=nil
5
- executions ||= 1
6
-
7
- statistics = ::Actor::Statistics.new
8
-
9
- executions.times do
10
- timer = Controls::Statistics::Timer.example
11
- statistics.timer = timer
12
-
13
- statistics.executing_action
14
- statistics.action_executed
15
- end
16
-
17
- statistics
18
- end
19
- end
20
- end
21
- end
@@ -1,31 +0,0 @@
1
- module Actor
2
- module Controls
3
- module Time
4
- class Clock
5
- attr_reader :step_function
6
- attr_accessor :time
7
-
8
- def initialize time, step_function
9
- @time = time
10
- @step_function = step_function
11
- end
12
-
13
- def self.build steps
14
- time = Time.reference
15
-
16
- step_function = steps.cycle
17
-
18
- new time, step_function
19
- end
20
-
21
- def now
22
- now = time
23
-
24
- self.time += step_function.next
25
-
26
- now
27
- end
28
- end
29
- end
30
- end
31
- end
@@ -1,24 +0,0 @@
1
- module Actor
2
- module Controls
3
- module Time
4
- def self.example offset=nil
5
- offset ||= 0
6
- offset = ElapsedTime.example offset
7
-
8
- reference + offset
9
- end
10
-
11
- def self.reference
12
- ::Time.new 2000, 1, 1, 11, 11, 11, -3600
13
- end
14
-
15
- module ElapsedTime
16
- def self.example scalar=nil
17
- scalar ||= 1
18
-
19
- Rational(scalar, 1000)
20
- end
21
- end
22
- end
23
- end
24
- end
data/lib/actor/message.rb DELETED
@@ -1,23 +0,0 @@
1
- module Actor
2
- module Message
3
- Pause = Class.new { include Message }
4
- Resume = Class.new { include Message }
5
- Stop = Class.new { include Message }
6
-
7
- class RecordStatus
8
- include Message
9
-
10
- attr_reader :reply_address
11
- attr_reader :status
12
-
13
- def initialize reply_address
14
- @reply_address = reply_address
15
- @status = Status.new
16
- end
17
- end
18
-
19
- class Status < OpenStruct
20
- include Message
21
- end
22
- end
23
- end
@@ -1,40 +0,0 @@
1
- module Actor
2
- module Messaging
3
- class Address
4
- attr_reader :id
5
- attr_reader :queue
6
-
7
- def initialize id, queue
8
- @id = id
9
- @queue = queue
10
- end
11
-
12
- def self.build
13
- id = SecureRandom.uuid
14
- queue = Queue.new
15
-
16
- new id, queue
17
- end
18
-
19
- def reader_count
20
- queue.reader_count
21
- end
22
-
23
- def inspect
24
- %{#<#{self.class.name} id=#{id.inspect}, queue=#{queue_tail}..#{queue_head}, readers=#{reader_count}>}
25
- end
26
-
27
- def queue_head
28
- queue.head
29
- end
30
-
31
- def queue_tail
32
- queue.tail
33
- end
34
-
35
- def queue_size
36
- queue.size
37
- end
38
- end
39
- end
40
- end
@@ -1,40 +0,0 @@
1
- module Actor
2
- module Messaging
3
- class Reader
4
- class Substitute
5
- attr_accessor :stopped
6
-
7
- def call wait: nil
8
- message = messages.shift
9
-
10
- return message if message
11
-
12
- if wait
13
- raise Wait, "Next message has not yet been written"
14
- end
15
- end
16
-
17
- def stop
18
- self.stopped = true
19
- end
20
-
21
- def stopped?
22
- stopped
23
- end
24
-
25
- def add_message message
26
- messages << message
27
- end
28
-
29
- def messages
30
- @messages ||= []
31
- end
32
-
33
- Wait = Class.new StandardError
34
-
35
- # Eventide compatibility
36
- singleton_class.send :alias_method, :build, :new
37
- end
38
- end
39
- end
40
- end
@@ -1,31 +0,0 @@
1
- module Actor
2
- module Messaging
3
- class Reader
4
- attr_reader :queue_reader
5
-
6
- def initialize queue_reader
7
- @queue_reader = queue_reader
8
- end
9
-
10
- def self.build address
11
- queue = address.queue
12
-
13
- queue_reader = Queue::Reader.build queue
14
-
15
- new queue_reader
16
- end
17
-
18
- def call wait: nil
19
- queue_reader.read wait: wait
20
- end
21
-
22
- def stop
23
- queue_reader.stop
24
- end
25
-
26
- def stopped?
27
- queue_reader.stopped?
28
- end
29
- end
30
- end
31
- end
@@ -1,26 +0,0 @@
1
- module Actor
2
- module Messaging
3
- class Writer
4
- attr_reader :queue
5
-
6
- def initialize queue
7
- @queue = queue
8
- end
9
-
10
- def self.build address
11
- queue = address.queue
12
-
13
- new queue
14
- end
15
-
16
- def self.call message, address
17
- instance = build address
18
- instance.(message)
19
- end
20
-
21
- def call message
22
- queue.write message
23
- end
24
- end
25
- end
26
- end
@@ -1,13 +0,0 @@
1
- module Actor
2
- class Queue
3
- module Assertions
4
- def contains? object
5
- if list.find object then true else false end
6
- end
7
-
8
- def empty?
9
- size.zero?
10
- end
11
- end
12
- end
13
- end
@@ -1,57 +0,0 @@
1
- module Actor
2
- class Queue
3
- class Reader
4
- attr_reader :queue
5
- attr_accessor :position
6
- attr_accessor :stopped
7
-
8
- def initialize queue, position
9
- @queue = queue
10
- @position = position
11
- end
12
-
13
- def self.build queue
14
- position = queue.reader_started
15
-
16
- new queue, position
17
- end
18
-
19
- def self.start queue, &block
20
- instance = build queue
21
-
22
- begin
23
- block.(instance)
24
- return instance
25
- ensure
26
- instance.stop
27
- end
28
- end
29
-
30
- def read wait: nil
31
- if stopped?
32
- raise Stopped, "Reader has stopped"
33
- end
34
-
35
- object = queue.read position, wait: wait
36
-
37
- return nil if object.nil?
38
-
39
- self.position = position.next
40
-
41
- object
42
- end
43
-
44
- def stop
45
- self.stopped = true
46
-
47
- queue.reader_stopped position
48
- end
49
-
50
- def stopped?
51
- stopped
52
- end
53
-
54
- Stopped = Class.new StandardError
55
- end
56
- end
57
- end
data/lib/actor/queue.rb DELETED
@@ -1,122 +0,0 @@
1
- module Actor
2
- class Queue
3
- attr_reader :blocked_threads
4
- attr_reader :reader_positions
5
- attr_reader :list
6
- attr_reader :mutex
7
- attr_reader :write_queue
8
- attr_accessor :tail
9
-
10
- def initialize
11
- @blocked_threads = Set.new
12
- @reader_positions = Hash.new 0
13
- @list = []
14
- @mutex = Mutex.new
15
- @write_queue = ::Queue.new
16
- @tail = 0
17
- end
18
-
19
- def head
20
- tail + size
21
- end
22
-
23
- def read position, wait: nil
24
- mutex.synchronize do
25
- relative_position = position - tail
26
-
27
- loop do
28
- flush_write_queue
29
-
30
- break if list.count > relative_position
31
-
32
- return nil unless wait
33
-
34
- blocked_threads << Thread.current
35
- mutex.sleep
36
- blocked_threads.delete Thread.current
37
- end
38
-
39
- object = list[relative_position]
40
-
41
- up position.next
42
- down position
43
-
44
- object
45
- end
46
- end
47
-
48
- def reader_started position=nil
49
- mutex.synchronize do
50
- position ||= tail
51
-
52
- up position
53
-
54
- position
55
- end
56
- end
57
-
58
- def readers?
59
- reader_positions.any?
60
- end
61
-
62
- def reader_count
63
- return 0 unless readers?
64
-
65
- reader_positions.values.reduce &:+
66
- end
67
-
68
- def reader_stopped position
69
- mutex.synchronize do
70
- down position
71
- end
72
- end
73
-
74
- def size
75
- list.size + write_queue.size
76
- end
77
-
78
- def write object
79
- return unless readers?
80
-
81
- write_queue << object
82
-
83
- blocked_threads.each &:wakeup
84
- end
85
-
86
- # These command methods are highly unsafe to call without owning the mutex;
87
- # therefore, they are marked as private.
88
- private
89
-
90
- def down position
91
- ref_count = reader_positions[position] - 1
92
-
93
- if ref_count.zero?
94
- reader_positions.delete position
95
- else
96
- reader_positions[position] = ref_count
97
- end
98
-
99
- if ref_count.zero?
100
- if readers? and position == tail
101
- new_tail = reader_positions.keys.min
102
-
103
- expired_objects = new_tail - tail
104
-
105
- list.slice! 0, expired_objects
106
-
107
- self.tail = new_tail
108
- end
109
- end
110
-
111
- ref_count
112
- end
113
-
114
- def flush_write_queue
115
- list << write_queue.deq until write_queue.empty?
116
- end
117
-
118
- def up position
119
- reader_positions[position] += 1
120
- end
121
- end
122
- end
@@ -1,19 +0,0 @@
1
- module Actor
2
- class Statistics
3
- module Copy
4
- def self.call target, statistics
5
- target.average_elapsed_time = statistics.average_elapsed_time
6
- target.elapsed_time = statistics.elapsed_time
7
- target.executions = statistics.executions
8
- target.last_execution_time = statistics.last_execution_time
9
- target.minimum_elapsed_time = statistics.minimum_elapsed_time
10
- target.maximum_elapsed_time = statistics.maximum_elapsed_time
11
- target.start_time = statistics.start_time
12
-
13
- deviation, _, _, percent = statistics.standard_deviation
14
- target.standard_deviation_amount = deviation
15
- target.standard_deviation_percent = percent
16
- end
17
- end
18
- end
19
- end
@@ -1,26 +0,0 @@
1
- module Actor
2
- class Statistics
3
- class Timer
4
- attr_writer :clock
5
- attr_accessor :start_time
6
- attr_accessor :stop_time
7
-
8
- def clock
9
- @clock ||= Time
10
- end
11
-
12
- def reset
13
- self.stop_time = nil
14
- self.start_time = clock.now
15
-
16
- start_time
17
- end
18
-
19
- def stop
20
- self.stop_time = stop_time = clock.now
21
-
22
- return start_time, stop_time
23
- end
24
- end
25
- end
26
- end
@@ -1,75 +0,0 @@
1
- module Actor
2
- class Statistics
3
- attr_accessor :elapsed_time
4
- attr_accessor :executions
5
- attr_accessor :last_execution_time
6
- attr_accessor :maximum_elapsed_time
7
- attr_accessor :minimum_elapsed_time
8
- attr_accessor :start_time
9
- attr_accessor :sum_elapsed_time_squared
10
- attr_writer :timer
11
-
12
- def initialize
13
- @executions = 0
14
- @elapsed_time = 0
15
- @sum_elapsed_time_squared = 0
16
- end
17
-
18
- def self.build actor
19
- instance = new
20
- actor.add_observer instance
21
- instance
22
- end
23
-
24
- def executing_action
25
- now = timer.reset
26
-
27
- self.start_time ||= now
28
- end
29
-
30
- def action_executed
31
- start_time, stop_time = timer.stop
32
-
33
- elapsed_time = stop_time - start_time
34
-
35
- self.elapsed_time += elapsed_time
36
- self.executions += 1
37
- self.last_execution_time = stop_time
38
- self.maximum_elapsed_time = [elapsed_time, maximum_elapsed_time].compact.max
39
- self.minimum_elapsed_time = [elapsed_time, minimum_elapsed_time].compact.min
40
- self.sum_elapsed_time_squared += elapsed_time ** 2
41
- end
42
-
43
- def average_elapsed_time
44
- return nil if executions.zero?
45
-
46
- Rational elapsed_time, executions
47
- end
48
-
49
- def standard_deviation
50
- return nil if executions.zero?
51
-
52
- average_elapsed_time = self.average_elapsed_time
53
-
54
- deviation = Math.sqrt(
55
- [
56
- 0,
57
- Rational(sum_elapsed_time_squared, executions) - average_elapsed_time ** 2
58
- ].max
59
- )
60
-
61
- min = average_elapsed_time - deviation
62
- max = average_elapsed_time + deviation
63
-
64
- unless average_elapsed_time.zero?
65
- percent = Rational(deviation * 100, average_elapsed_time)
66
- end
67
-
68
- return deviation, min, max, percent
69
- end
70
-
71
- def timer
72
- @timer ||= Timer.new
73
- end
74
- end
75
- end