ntl-actor 0.3.1 → 0.4.0.pre1

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