observed 0.2.0.rc1 → 0.2.0.rc2
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 +8 -8
- data/lib/observed/basic_event_bus.rb +32 -0
- data/lib/observed/config_builder.rb +15 -10
- data/lib/observed/context.rb +9 -9
- data/lib/observed/event_bus.rb +16 -19
- data/lib/observed/{execution_job_factory.rb → observed_task_factory.rb} +9 -9
- data/lib/observed/{job.rb → task.rb} +55 -47
- data/lib/observed/version.rb +1 -1
- data/run-integration-tests +2 -0
- data/spec/basic_event_bus_spec.rb +16 -0
- data/spec/event_bus_spec.rb +24 -10
- data/spec/observed_spec.rb +97 -32
- data/spec/{execution_job_factory_spec.rb → observed_task_factory_spec.rb} +8 -8
- data/spec/{job_factory_spec.rb → task_factory_spec.rb} +4 -4
- data/spec/{job_spec.rb → task_spec.rb} +57 -57
- metadata +13 -13
- data/lib/observed/jobbed_event_bus.rb +0 -33
- data/spec/jobbed_event_bus_spec.rb +0 -38
checksums.yaml
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
!binary "U0hBMQ==":
|
|
3
3
|
metadata.gz: !binary |-
|
|
4
|
-
|
|
4
|
+
YjRlMjYwYzAwNDlkNzZiM2RkNzllNGRhYjgxMGQyNGEzMjFiMzBiNw==
|
|
5
5
|
data.tar.gz: !binary |-
|
|
6
|
-
|
|
6
|
+
NDg2OTI4MDVjNzcxNTczMGE3YWNhZmM5Zjk3M2RlYjc1MWYzZjllNg==
|
|
7
7
|
SHA512:
|
|
8
8
|
metadata.gz: !binary |-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
NzkyMGY1NzMzOWM3NTJmZDlhMTE3OTQyYzk1MTU4N2U5ZWU3YTY4NzRlNDc5
|
|
10
|
+
ZmM0ZTIxNDQ5ODFiNGIxN2Y4NDhkZjFhM2ViMjhkNWMzNjFiY2ZhY2U4MWE5
|
|
11
|
+
NzIzMmI1NjNkNTUzY2FhMWE1NjlmOTMyMDY4OTRjY2QxZTZlYTc=
|
|
12
12
|
data.tar.gz: !binary |-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
OTdkODQ1YzhhOWRlMzA1NGY1OGFjY2UzOWU5NjA2OTU2NjBiZWU4Y2RjNmE0
|
|
14
|
+
Y2I0MDJkNzdhNzZhOGQ3ZWUzOTExZDI2ODMwM2M2MmE0YzFiYTAwN2JmOWI1
|
|
15
|
+
ZGM2ZDNiNTQzZmIyMWEwYjIzNGJhNmVlNjVlZTVmMjU0M2E4NGE=
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require 'thread'
|
|
2
|
+
require 'monitor'
|
|
3
|
+
|
|
4
|
+
module Observed
|
|
5
|
+
class BasicEventBus
|
|
6
|
+
def initialize
|
|
7
|
+
@monitor = ::Monitor.new
|
|
8
|
+
@subscribers = []
|
|
9
|
+
end
|
|
10
|
+
def emit(tag, *params)
|
|
11
|
+
handle_event(tag, *params)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def on_receive(pattern, &block)
|
|
15
|
+
@monitor.synchronize do
|
|
16
|
+
@subscribers.push [pattern, block]
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def handle_event(tag, *params)
|
|
23
|
+
@monitor.synchronize do
|
|
24
|
+
@subscribers.each do |pattern, s|
|
|
25
|
+
if pattern.match(tag)
|
|
26
|
+
s.call *params
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -6,7 +6,7 @@ require 'observed/configurable'
|
|
|
6
6
|
require 'observed/default'
|
|
7
7
|
require 'observed/hash'
|
|
8
8
|
require 'observed/translator'
|
|
9
|
-
require 'observed/
|
|
9
|
+
require 'observed/observed_task_factory'
|
|
10
10
|
|
|
11
11
|
module Observed
|
|
12
12
|
|
|
@@ -110,7 +110,7 @@ module Observed
|
|
|
110
110
|
end
|
|
111
111
|
|
|
112
112
|
reporters << reporter
|
|
113
|
-
report_it =
|
|
113
|
+
report_it = convert_to_task(reporter)
|
|
114
114
|
if tag_pattern
|
|
115
115
|
receive(tag_pattern).then(report_it)
|
|
116
116
|
end
|
|
@@ -167,7 +167,7 @@ module Observed
|
|
|
167
167
|
else
|
|
168
168
|
fail "No args valid args (in args=#{args}) or a block given"
|
|
169
169
|
end
|
|
170
|
-
observe_that =
|
|
170
|
+
observe_that = convert_to_task(observer)
|
|
171
171
|
result = if tag
|
|
172
172
|
a = observe_that.then(emit(tag))
|
|
173
173
|
group tag, (group(tag) + [a])
|
|
@@ -176,6 +176,7 @@ module Observed
|
|
|
176
176
|
observe_that
|
|
177
177
|
end
|
|
178
178
|
observers << result
|
|
179
|
+
result.name = "observe"
|
|
179
180
|
result
|
|
180
181
|
end
|
|
181
182
|
|
|
@@ -191,15 +192,19 @@ module Observed
|
|
|
191
192
|
else
|
|
192
193
|
Observed::ProcTranslator.new &block
|
|
193
194
|
end
|
|
194
|
-
|
|
195
|
+
task = convert_to_task(translator)
|
|
196
|
+
task.name = "translate"
|
|
197
|
+
task
|
|
195
198
|
end
|
|
196
199
|
|
|
197
200
|
def emit(tag)
|
|
198
|
-
@context.
|
|
201
|
+
e = @context.event_bus.emit(tag)
|
|
202
|
+
e.name = "emit to #{tag}"
|
|
203
|
+
e
|
|
199
204
|
end
|
|
200
205
|
|
|
201
206
|
def receive(pattern)
|
|
202
|
-
@context.
|
|
207
|
+
@context.event_bus.receive(pattern)
|
|
203
208
|
end
|
|
204
209
|
|
|
205
210
|
# Updates or get the observations belongs to the group named `name`
|
|
@@ -212,7 +217,7 @@ module Observed
|
|
|
212
217
|
end
|
|
213
218
|
|
|
214
219
|
def run_group(name)
|
|
215
|
-
@context.
|
|
220
|
+
@context.task_factory.parallel(group(name))
|
|
216
221
|
end
|
|
217
222
|
|
|
218
223
|
def reporters
|
|
@@ -225,9 +230,9 @@ module Observed
|
|
|
225
230
|
|
|
226
231
|
private
|
|
227
232
|
|
|
228
|
-
def
|
|
229
|
-
@
|
|
230
|
-
@
|
|
233
|
+
def convert_to_task(underlying)
|
|
234
|
+
@observed_task_factory ||= @context.observed_task_factory
|
|
235
|
+
@observed_task_factory.convert_to_task(underlying)
|
|
231
236
|
end
|
|
232
237
|
end
|
|
233
238
|
|
data/lib/observed/context.rb
CHANGED
|
@@ -3,8 +3,8 @@ require 'logger'
|
|
|
3
3
|
require 'observed/system'
|
|
4
4
|
require 'observed/config_builder'
|
|
5
5
|
require 'observed/config_dsl'
|
|
6
|
-
require 'observed/
|
|
7
|
-
require 'observed/
|
|
6
|
+
require 'observed/task'
|
|
7
|
+
require 'observed/event_bus'
|
|
8
8
|
|
|
9
9
|
module Observed
|
|
10
10
|
# The run context of an Observed system.
|
|
@@ -46,19 +46,19 @@ module Observed
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def executor
|
|
49
|
-
@executor ||= Observed::
|
|
49
|
+
@executor ||= Observed::BlockingExecutor.new
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
-
def
|
|
53
|
-
@event_bus ||= Observed::
|
|
52
|
+
def event_bus
|
|
53
|
+
@event_bus ||= Observed::EventBus.new(task_factory: task_factory)
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
-
def
|
|
57
|
-
@
|
|
56
|
+
def task_factory
|
|
57
|
+
@task_factory ||= Observed::TaskFactory.new(executor: executor)
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
-
def
|
|
61
|
-
@
|
|
60
|
+
def observed_task_factory
|
|
61
|
+
@observed_task_factory ||= Observed::ObservedTaskFactory.new(task_factory: task_factory)
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
def config_builder
|
data/lib/observed/event_bus.rb
CHANGED
|
@@ -1,31 +1,28 @@
|
|
|
1
1
|
require 'thread'
|
|
2
|
+
require 'observed/basic_event_bus'
|
|
2
3
|
|
|
3
4
|
module Observed
|
|
4
5
|
class EventBus
|
|
5
|
-
def initialize
|
|
6
|
+
def initialize(args={})
|
|
7
|
+
@bus = Observed::BasicEventBus.new
|
|
8
|
+
@receives = {}
|
|
9
|
+
@task_factory = args[:task_factory] || fail("The parameter :task_factory is missing in args(#{args}")
|
|
6
10
|
@mutex = ::Mutex.new
|
|
7
|
-
@subscribers = []
|
|
8
11
|
end
|
|
9
12
|
def emit(tag, *params)
|
|
10
|
-
|
|
13
|
+
@task_factory.task { |*params|
|
|
14
|
+
@bus.emit tag, *params
|
|
15
|
+
params
|
|
16
|
+
}
|
|
11
17
|
end
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
private
|
|
20
|
-
|
|
21
|
-
def handle_event(tag, *params)
|
|
22
|
-
@mutex.synchronize do
|
|
23
|
-
@subscribers.each do |pattern, s|
|
|
24
|
-
if pattern.match(tag)
|
|
25
|
-
s.call *params
|
|
26
|
-
end
|
|
27
|
-
end
|
|
18
|
+
def receive(pattern)
|
|
19
|
+
task = @task_factory.mutable_task {|data, options|
|
|
20
|
+
[data, options]
|
|
21
|
+
}
|
|
22
|
+
@bus.on_receive(pattern) do |*params|
|
|
23
|
+
task.now(*params)
|
|
28
24
|
end
|
|
25
|
+
task
|
|
29
26
|
end
|
|
30
27
|
end
|
|
31
28
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require 'observed/observer'
|
|
2
2
|
require 'observed/reporter'
|
|
3
3
|
require 'observed/translator'
|
|
4
|
-
require 'observed/
|
|
4
|
+
require 'observed/task'
|
|
5
5
|
|
|
6
6
|
module Observed
|
|
7
7
|
# An yet another cushion from the deprecated plugin interface to the new plugin interface
|
|
@@ -38,16 +38,16 @@ module Observed
|
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
class
|
|
41
|
+
class ObservedTaskFactory
|
|
42
42
|
|
|
43
43
|
def initialize(args={})
|
|
44
|
-
@
|
|
44
|
+
@task_factory = args[:task_factory] || Observed::TaskFactory.new(executor: Observed::BlockingExecutor.new)
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
# Convert the observer/translator/reporter to a
|
|
48
|
-
def
|
|
47
|
+
# Convert the observer/translator/reporter to a task
|
|
48
|
+
def convert_to_task(underlying)
|
|
49
49
|
if underlying.is_a? Observed::Observer
|
|
50
|
-
@
|
|
50
|
+
@task_factory.task {|data, options|
|
|
51
51
|
options ||= {}
|
|
52
52
|
m = underlying.method(:observe)
|
|
53
53
|
fake_system = FakeSystem.new(time: options[:time])
|
|
@@ -58,19 +58,19 @@ module Observed
|
|
|
58
58
|
fake_system.reported || result
|
|
59
59
|
}
|
|
60
60
|
elsif underlying.is_a? Observed::Reporter
|
|
61
|
-
@
|
|
61
|
+
@task_factory.task {|data, options|
|
|
62
62
|
options ||= {}
|
|
63
63
|
m = underlying.method(:report)
|
|
64
64
|
dispatch_method m, data, options
|
|
65
65
|
}
|
|
66
66
|
elsif underlying.is_a? Observed::Translator
|
|
67
|
-
@
|
|
67
|
+
@task_factory.task {|data, options|
|
|
68
68
|
options ||= {}
|
|
69
69
|
m = underlying.method(:translate)
|
|
70
70
|
dispatch_method m, data, options
|
|
71
71
|
}
|
|
72
72
|
else
|
|
73
|
-
fail "Unexpected type of object which can not be converted to a
|
|
73
|
+
fail "Unexpected type of object which can not be converted to a task: #{underlying}"
|
|
74
74
|
end
|
|
75
75
|
end
|
|
76
76
|
|
|
@@ -2,81 +2,89 @@ require 'logger'
|
|
|
2
2
|
require 'thread'
|
|
3
3
|
|
|
4
4
|
module Observed
|
|
5
|
-
class
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
class Task
|
|
6
|
+
attr_accessor :name
|
|
7
|
+
|
|
8
|
+
def then(*tasks)
|
|
9
|
+
next_task = if tasks.size == 1
|
|
10
|
+
tasks.first
|
|
11
|
+
elsif tasks.size > 1
|
|
12
|
+
ParallelTask.new(tasks)
|
|
11
13
|
else
|
|
12
|
-
raise 'No
|
|
14
|
+
raise 'No tasks to be executed'
|
|
13
15
|
end
|
|
14
|
-
|
|
16
|
+
SequenceTask.new(self, next_task)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def compose(first_task)
|
|
20
|
+
second_task = self
|
|
21
|
+
|
|
22
|
+
first_task.then(second_task)
|
|
15
23
|
end
|
|
16
24
|
end
|
|
17
25
|
|
|
18
|
-
class
|
|
19
|
-
def initialize(
|
|
20
|
-
@
|
|
26
|
+
class MutableTask
|
|
27
|
+
def initialize(current_task)
|
|
28
|
+
@current_task = current_task
|
|
21
29
|
@mutex = Mutex.new
|
|
22
30
|
end
|
|
23
31
|
def now(data={}, options=nil)
|
|
24
|
-
@
|
|
32
|
+
@current_task.now(data, options) do |data, options2|
|
|
25
33
|
yield data, (options2 || options) if block_given?
|
|
26
34
|
end
|
|
27
35
|
end
|
|
28
|
-
def then(*
|
|
36
|
+
def then(*tasks)
|
|
29
37
|
@mutex.synchronize do
|
|
30
|
-
@
|
|
38
|
+
@current_task = @current_task.then(*tasks)
|
|
31
39
|
end
|
|
32
40
|
self
|
|
33
41
|
end
|
|
34
42
|
end
|
|
35
43
|
|
|
36
|
-
class
|
|
37
|
-
attr_reader :
|
|
38
|
-
def initialize(
|
|
39
|
-
@
|
|
40
|
-
@
|
|
44
|
+
class SequenceTask < Observed::Task
|
|
45
|
+
attr_reader :base_task
|
|
46
|
+
def initialize(base_task, next_task)
|
|
47
|
+
@base_task = base_task
|
|
48
|
+
@next_task = next_task
|
|
41
49
|
end
|
|
42
50
|
def now(data={}, options=nil)
|
|
43
|
-
@
|
|
44
|
-
@
|
|
51
|
+
@base_task.now(data, options) do |data, options2|
|
|
52
|
+
@next_task.now(data, (options2 || options)) do |data, options3|
|
|
45
53
|
yield data, (options3 || options2 || options) if block_given?
|
|
46
54
|
end
|
|
47
55
|
end
|
|
48
56
|
end
|
|
49
57
|
end
|
|
50
58
|
|
|
51
|
-
class
|
|
52
|
-
def initialize(
|
|
53
|
-
@
|
|
54
|
-
@
|
|
59
|
+
class ParallelTask < Observed::Task
|
|
60
|
+
def initialize(tasks)
|
|
61
|
+
@tasks = tasks || fail('tasks missing')
|
|
62
|
+
@next_task = NoOpTask.instance
|
|
55
63
|
end
|
|
56
64
|
def now(data={}, options=nil)
|
|
57
|
-
@
|
|
58
|
-
|
|
65
|
+
@tasks.each do |task|
|
|
66
|
+
task.now(data, options) do |data, options2|
|
|
59
67
|
yield data, (options2 || options) if block_given?
|
|
60
68
|
end
|
|
61
69
|
end
|
|
62
70
|
end
|
|
63
71
|
end
|
|
64
72
|
|
|
65
|
-
class
|
|
73
|
+
class NoOpTask < Observed::Task
|
|
66
74
|
def now(data={}, options={}); end
|
|
67
75
|
def self.instance
|
|
68
76
|
SINGLETON_INSTANCE
|
|
69
77
|
end
|
|
70
|
-
SINGLETON_INSTANCE =
|
|
78
|
+
SINGLETON_INSTANCE = NoOpTask.new
|
|
71
79
|
end
|
|
72
80
|
|
|
73
|
-
class
|
|
81
|
+
class ProcTask < Observed::Task
|
|
74
82
|
def initialize(args, &block)
|
|
75
83
|
@executor = args[:executor] || fail('Missing a value for :executor')
|
|
76
84
|
@listener = args[:listener] || fail('Missing a value for :listener')
|
|
77
85
|
@logger = args[:logger]
|
|
78
86
|
@block = block
|
|
79
|
-
@
|
|
87
|
+
@next_task = NoOpTask.instance
|
|
80
88
|
|
|
81
89
|
if @logger.nil?
|
|
82
90
|
@logger = ::Logger.new(STDERR)
|
|
@@ -84,7 +92,7 @@ module Observed
|
|
|
84
92
|
end
|
|
85
93
|
end
|
|
86
94
|
def now(data={}, options=nil)
|
|
87
|
-
@executor.
|
|
95
|
+
@executor.submit {
|
|
88
96
|
result = @block.call(data, options)
|
|
89
97
|
yield result if block_given?
|
|
90
98
|
notify_listener(data: data, options: options, result: result)
|
|
@@ -118,43 +126,43 @@ module Observed
|
|
|
118
126
|
end
|
|
119
127
|
end
|
|
120
128
|
|
|
121
|
-
class
|
|
129
|
+
class TaskListener
|
|
122
130
|
def on_result(data={}, options={})
|
|
123
131
|
|
|
124
132
|
end
|
|
125
133
|
end
|
|
126
134
|
|
|
127
|
-
class
|
|
135
|
+
class TaskFactory
|
|
128
136
|
def initialize(args)
|
|
129
137
|
@executor = args[:executor] || fail('Missing a value for :executor')
|
|
130
|
-
@listener = args[:listener] ||
|
|
138
|
+
@listener = args[:listener] || TaskListener.new
|
|
131
139
|
end
|
|
132
140
|
|
|
133
|
-
def
|
|
134
|
-
|
|
141
|
+
def task(&block)
|
|
142
|
+
ProcTask.new(executor: @executor, listener: @listener, &block)
|
|
135
143
|
end
|
|
136
144
|
|
|
137
|
-
def
|
|
138
|
-
|
|
145
|
+
def mutable_task(&block)
|
|
146
|
+
MutableTask.new(task(&block))
|
|
139
147
|
end
|
|
140
148
|
|
|
141
|
-
def parallel(
|
|
142
|
-
|
|
149
|
+
def parallel(tasks)
|
|
150
|
+
ParallelTask.new(tasks)
|
|
143
151
|
end
|
|
144
152
|
end
|
|
145
153
|
|
|
146
|
-
class
|
|
147
|
-
def
|
|
154
|
+
class Executor
|
|
155
|
+
def submit; end
|
|
148
156
|
end
|
|
149
157
|
|
|
150
|
-
class
|
|
151
|
-
def
|
|
158
|
+
class BlockingExecutor
|
|
159
|
+
def submit
|
|
152
160
|
yield
|
|
153
161
|
end
|
|
154
162
|
end
|
|
155
163
|
|
|
156
|
-
class
|
|
157
|
-
def
|
|
164
|
+
class ThreadExecutor
|
|
165
|
+
def submit
|
|
158
166
|
Thread.start {
|
|
159
167
|
yield
|
|
160
168
|
}
|
data/lib/observed/version.rb
CHANGED
data/run-integration-tests
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'observed/basic_event_bus'
|
|
3
|
+
|
|
4
|
+
describe Observed::BasicEventBus do
|
|
5
|
+
it 'calls the handler for the emitted event' do
|
|
6
|
+
handler_one_called = false
|
|
7
|
+
handler_two_called = false
|
|
8
|
+
bus = Observed::BasicEventBus.new
|
|
9
|
+
expect { bus.emit('foo') }.to_not raise_error
|
|
10
|
+
expect { bus.on_receive(/^bar$/) { handler_one_called = true } }.to_not raise_error
|
|
11
|
+
expect { bus.on_receive(/^baz$/) { handler_two_called = true } }.to_not raise_error
|
|
12
|
+
expect { bus.emit('bar') }.to_not raise_error
|
|
13
|
+
expect(handler_one_called).to be_true
|
|
14
|
+
expect(handler_two_called).to be_false
|
|
15
|
+
end
|
|
16
|
+
end
|
data/spec/event_bus_spec.rb
CHANGED
|
@@ -1,16 +1,30 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
require 'observed/task'
|
|
2
4
|
require 'observed/event_bus'
|
|
3
5
|
|
|
4
6
|
describe Observed::EventBus do
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
let(:out) {
|
|
8
|
+
mock('out')
|
|
9
|
+
}
|
|
10
|
+
let(:factory) {
|
|
11
|
+
executor = Observed::BlockingExecutor.new
|
|
12
|
+
Observed::TaskFactory.new(executor: executor)
|
|
13
|
+
}
|
|
14
|
+
let(:the_task) {
|
|
15
|
+
factory.task { |data, options|
|
|
16
|
+
out.write data, options
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
let(:bus) {
|
|
20
|
+
Observed::EventBus.new(task_factory: factory)
|
|
21
|
+
}
|
|
22
|
+
it 'should invoke tasks when the corresponding events are emitted' do
|
|
23
|
+
bus.emit('foo').now
|
|
24
|
+
bus.receive(/^bar$/).then(the_task)
|
|
25
|
+
bus.emit('baz').now
|
|
26
|
+
out.expects(:write).with({a:1}, {b:2})
|
|
27
|
+
bus.emit('bar').now({a:1}, {b:2})
|
|
28
|
+
bus.emit('blah').now
|
|
15
29
|
end
|
|
16
30
|
end
|
data/spec/observed_spec.rb
CHANGED
|
@@ -79,9 +79,9 @@ describe Observed do
|
|
|
79
79
|
|
|
80
80
|
describe 'when included' do
|
|
81
81
|
subject {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
ctx = ::Object.new
|
|
83
|
+
ctx.extend Observed
|
|
84
|
+
ctx
|
|
85
85
|
}
|
|
86
86
|
let(:t) {
|
|
87
87
|
Time.now
|
|
@@ -91,11 +91,11 @@ describe Observed do
|
|
|
91
91
|
}
|
|
92
92
|
let(:out) {
|
|
93
93
|
out = mock('out1')
|
|
94
|
-
out.expects(:write).with(tag:'t', foo:1, foo2:1, bar:2, bar2:2, baz:3, baz2:3, r3:'common', time: t)
|
|
95
|
-
.at_least_once
|
|
96
94
|
out
|
|
97
95
|
}
|
|
98
96
|
it 'can be used to define components and trigger them immediately' do
|
|
97
|
+
out.expects(:write).with(tag:'t', foo:1, foo2:1, bar:2, bar2:2, baz:3, baz2:3, r3:'common', time: t)
|
|
98
|
+
.at_least_once
|
|
99
99
|
report_to_out = subject.report do |data, options|
|
|
100
100
|
out.write data.merge(baz2:data[:baz]).merge(r3: common).merge(options)
|
|
101
101
|
end
|
|
@@ -139,6 +139,9 @@ describe Observed do
|
|
|
139
139
|
out.write data.merge({baz2:data[:baz],r3:common}.merge(options))
|
|
140
140
|
end
|
|
141
141
|
end
|
|
142
|
+
|
|
143
|
+
out.expects(:write).with(tag:'t', foo:1, foo2:1, bar:2, bar2:2, baz:3, baz2:3, r3:'common', time: t)
|
|
144
|
+
.at_least_once
|
|
142
145
|
}
|
|
143
146
|
it 'can be used to define components from plugins and trigger them immediately' do
|
|
144
147
|
observe_then_translate_then_report = (subject.observe via: 'test1')
|
|
@@ -148,52 +151,52 @@ describe Observed do
|
|
|
148
151
|
observe_then_translate_then_report.now({foo:1}, {tag: 't', time: t, out: out})
|
|
149
152
|
end
|
|
150
153
|
it 'can be used to send and receive tagged events' do
|
|
151
|
-
require 'observed/
|
|
152
|
-
require 'observed/
|
|
153
|
-
executor = Observed::
|
|
154
|
-
|
|
155
|
-
bus = Observed::
|
|
154
|
+
require 'observed/task'
|
|
155
|
+
require 'observed/event_bus'
|
|
156
|
+
executor = Observed::BlockingExecutor.new
|
|
157
|
+
task_factory = Observed::TaskFactory.new(executor: executor)
|
|
158
|
+
bus = Observed::EventBus.new(task_factory: task_factory)
|
|
156
159
|
|
|
157
160
|
observe_then_send = (subject.observe via: 'test1')
|
|
158
|
-
.then(bus.
|
|
161
|
+
.then(bus.emit 'foo1')
|
|
159
162
|
|
|
160
|
-
bus.receive(/
|
|
163
|
+
bus.receive(/foo1/)
|
|
161
164
|
.then(subject.translate via: 'test1')
|
|
162
165
|
.then(subject.report via: 'test1', with: {common: common})
|
|
163
166
|
|
|
164
167
|
observe_then_send.now({foo:1}, {tag: 't', time: t, out: out})
|
|
165
168
|
end
|
|
166
169
|
it 'can be used to send and receive tagged events with the default event bus' do
|
|
167
|
-
require 'observed/
|
|
170
|
+
require 'observed/task'
|
|
168
171
|
|
|
169
|
-
subject.configure executor: Observed::
|
|
172
|
+
subject.configure executor: Observed::BlockingExecutor.new
|
|
170
173
|
|
|
171
174
|
observe_then_send = (subject.observe via: 'test1')
|
|
172
|
-
.then(subject.emit '
|
|
175
|
+
.then(subject.emit 'foo2')
|
|
173
176
|
|
|
174
|
-
subject.receive(/
|
|
177
|
+
subject.receive(/foo2/)
|
|
175
178
|
.then(subject.translate via: 'test1')
|
|
176
179
|
.then(subject.report via: 'test1', with: {common: common})
|
|
177
180
|
|
|
178
181
|
observe_then_send.now({foo:1}, {tag: 't', time: t, out: out})
|
|
179
182
|
end
|
|
180
183
|
it 'provides the way to send the tagged events with a bit shorter code' do
|
|
181
|
-
require 'observed/
|
|
184
|
+
require 'observed/task'
|
|
182
185
|
|
|
183
|
-
subject.configure executor: Observed::
|
|
186
|
+
subject.configure executor: Observed::BlockingExecutor.new
|
|
184
187
|
|
|
185
|
-
observe_then_send = (subject.observe '
|
|
188
|
+
observe_then_send = (subject.observe 'foo3', via: 'test1')
|
|
186
189
|
|
|
187
|
-
subject.receive(/
|
|
190
|
+
subject.receive(/foo3/)
|
|
188
191
|
.then(subject.translate via: 'test1')
|
|
189
192
|
.then(subject.report via: 'test1', with: {out: out, common: common})
|
|
190
193
|
|
|
191
194
|
observe_then_send.now({foo:1}, {tag: 't', time: t, out: out})
|
|
192
195
|
end
|
|
193
196
|
it 'provides the way to receive the tagged events with a bit shorter code' do
|
|
194
|
-
require 'observed/
|
|
197
|
+
require 'observed/task'
|
|
195
198
|
|
|
196
|
-
subject.configure executor: Observed::
|
|
199
|
+
subject.configure executor: Observed::BlockingExecutor.new
|
|
197
200
|
|
|
198
201
|
observe_then_send = (subject.observe via: 'test1')
|
|
199
202
|
.then(subject.translate via: 'test1')
|
|
@@ -204,9 +207,9 @@ describe Observed do
|
|
|
204
207
|
observe_then_send.now({foo:1}, {tag: 't', time: t, out: out})
|
|
205
208
|
end
|
|
206
209
|
it 'provides the way to group up observations' do
|
|
207
|
-
require 'observed/
|
|
210
|
+
require 'observed/task'
|
|
208
211
|
|
|
209
|
-
subject.configure executor: Observed::
|
|
212
|
+
subject.configure executor: Observed::BlockingExecutor.new
|
|
210
213
|
|
|
211
214
|
subject.group :a, [
|
|
212
215
|
(subject.observe via: 'test1')
|
|
@@ -221,9 +224,9 @@ describe Observed do
|
|
|
221
224
|
end
|
|
222
225
|
end
|
|
223
226
|
it 'provides the way to group up observations by their tags' do
|
|
224
|
-
require 'observed/
|
|
227
|
+
require 'observed/task'
|
|
225
228
|
|
|
226
|
-
subject.configure executor: Observed::
|
|
229
|
+
subject.configure executor: Observed::BlockingExecutor.new
|
|
227
230
|
|
|
228
231
|
subject.observe 'hoge', via: 'test1'
|
|
229
232
|
|
|
@@ -236,9 +239,9 @@ describe Observed do
|
|
|
236
239
|
end
|
|
237
240
|
end
|
|
238
241
|
it 'provides the way to run a group of observations in single method call' do
|
|
239
|
-
require 'observed/
|
|
242
|
+
require 'observed/task'
|
|
240
243
|
|
|
241
|
-
subject.configure executor: Observed::
|
|
244
|
+
subject.configure executor: Observed::BlockingExecutor.new
|
|
242
245
|
|
|
243
246
|
subject.observe 'hoge', via: 'test1'
|
|
244
247
|
|
|
@@ -249,9 +252,9 @@ describe Observed do
|
|
|
249
252
|
subject.run_group('hoge').now({foo:1}, {tag: 't', time: t, out: out})
|
|
250
253
|
end
|
|
251
254
|
it 'provides a short-cut for running a group of observations' do
|
|
252
|
-
require 'observed/
|
|
255
|
+
require 'observed/task'
|
|
253
256
|
|
|
254
|
-
subject.configure executor: Observed::
|
|
257
|
+
subject.configure executor: Observed::BlockingExecutor.new
|
|
255
258
|
|
|
256
259
|
subject.observe 'fuga', via: 'test1'
|
|
257
260
|
|
|
@@ -262,9 +265,9 @@ describe Observed do
|
|
|
262
265
|
subject.run('fuga', {foo:1}, {tag: 't', time: t, out: out})
|
|
263
266
|
end
|
|
264
267
|
it 'provides the default values for the option `tag` and `time`' do
|
|
265
|
-
require 'observed/
|
|
268
|
+
require 'observed/task'
|
|
266
269
|
|
|
267
|
-
subject.configure executor: Observed::
|
|
270
|
+
subject.configure executor: Observed::BlockingExecutor.new
|
|
268
271
|
|
|
269
272
|
subject.observe 't', via: 'test1'
|
|
270
273
|
|
|
@@ -276,6 +279,68 @@ describe Observed do
|
|
|
276
279
|
|
|
277
280
|
subject.run('t', {foo:1}, {out: out})
|
|
278
281
|
end
|
|
282
|
+
it 'allows to use emit/receive for subscribing to internal events' do
|
|
283
|
+
require 'observed/task'
|
|
284
|
+
|
|
285
|
+
subject.configure executor: Observed::BlockingExecutor.new
|
|
286
|
+
|
|
287
|
+
subject.receive('foo123')
|
|
288
|
+
.then(
|
|
289
|
+
(subject.observe via: 'test1')
|
|
290
|
+
.then(subject.translate via: 'test1')
|
|
291
|
+
.then(subject.report via: 'test1', with: {out: out, common: common})
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
::Time.stubs(now: t)
|
|
295
|
+
|
|
296
|
+
subject.emit('foo123').now({foo:1}, {out: out, tag: 't', time: Time.now})
|
|
297
|
+
end
|
|
298
|
+
it 'allows to use emit/receive for subscribing to internal events to trigger receive/translate/report' do
|
|
299
|
+
require 'observed/task'
|
|
300
|
+
|
|
301
|
+
subject.configure executor: Observed::BlockingExecutor.new
|
|
302
|
+
|
|
303
|
+
subject.receive('kuroko1')
|
|
304
|
+
.then(subject.observe via: 'test1')
|
|
305
|
+
.then(subject.translate via: 'test1')
|
|
306
|
+
.then(subject.emit 'kuroko2')
|
|
307
|
+
|
|
308
|
+
subject.receive('kuroko2')
|
|
309
|
+
.then(subject.report via: 'test1', with: {out: out, common: common})
|
|
310
|
+
|
|
311
|
+
::Time.stubs(now: t)
|
|
312
|
+
|
|
313
|
+
subject.emit('kuroko1').now({foo:1}, {out: out, tag: 't', time: Time.now})
|
|
314
|
+
end
|
|
315
|
+
it 'allows to just report something' do
|
|
316
|
+
require 'observed/task'
|
|
317
|
+
|
|
318
|
+
subject.configure executor: Observed::BlockingExecutor.new
|
|
319
|
+
|
|
320
|
+
subject.receive('kuroko3')
|
|
321
|
+
.then(subject.report via: 'test1', with: {out: out, common: common})
|
|
322
|
+
|
|
323
|
+
::Time.stubs(now: t)
|
|
324
|
+
|
|
325
|
+
subject.emit('kuroko3').now({foo:1, foo2:1, bar:2, bar2:2, baz: 3, baz2:3, r3: common}, {out: out, tag: 't', time: Time.now})
|
|
326
|
+
end
|
|
327
|
+
it 'allows a kind of reactive programming' do
|
|
328
|
+
require 'observed/task'
|
|
329
|
+
|
|
330
|
+
subject.configure executor: Observed::BlockingExecutor.new
|
|
331
|
+
|
|
332
|
+
subject.report(via: 'test1', with: {out: out, common: common}).compose(
|
|
333
|
+
subject.translate(via: 'test1').compose(
|
|
334
|
+
subject.observe(via: 'test1').compose(
|
|
335
|
+
subject.receive('kuroko4')
|
|
336
|
+
)
|
|
337
|
+
)
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
::Time.stubs(now: t)
|
|
341
|
+
|
|
342
|
+
subject.emit('kuroko4').now({foo:1, foo2:1, bar:2, bar2:2, baz: 3, baz2:3, r3: common}, {out: out, tag: 't', time: Time.now})
|
|
343
|
+
end
|
|
279
344
|
end
|
|
280
345
|
|
|
281
346
|
end
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
|
-
require 'observed/
|
|
2
|
+
require 'observed/observed_task_factory'
|
|
3
3
|
|
|
4
|
-
describe Observed::
|
|
4
|
+
describe Observed::ObservedTaskFactory do
|
|
5
5
|
subject {
|
|
6
|
-
Observed::
|
|
6
|
+
Observed::ObservedTaskFactory.new
|
|
7
7
|
}
|
|
8
|
-
it 'should convert observers, translators, reporters to
|
|
8
|
+
it 'should convert observers, translators, reporters to tasks' do
|
|
9
9
|
output = mock('output')
|
|
10
10
|
|
|
11
11
|
the_observer = Class.new(Observed::Observer) do
|
|
@@ -24,12 +24,12 @@ describe Observed::ExecutionJobFactory do
|
|
|
24
24
|
data.merge(c:3)
|
|
25
25
|
end
|
|
26
26
|
end.new
|
|
27
|
-
|
|
28
|
-
.then(subject.
|
|
29
|
-
.then(subject.
|
|
27
|
+
task = subject.convert_to_task(the_observer)
|
|
28
|
+
.then(subject.convert_to_task(the_translator))
|
|
29
|
+
.then(subject.convert_to_task(the_reporter))
|
|
30
30
|
tag = 'the_tag'
|
|
31
31
|
time = Time.now
|
|
32
32
|
output.expects(:write).with(tag: tag, time: time, data: {a:1,b:2,c:3})
|
|
33
|
-
|
|
33
|
+
task.now({a:1}, {tag: tag, time: time})
|
|
34
34
|
end
|
|
35
35
|
end
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
|
-
require 'observed/
|
|
2
|
+
require 'observed/task'
|
|
3
3
|
|
|
4
|
-
describe Observed::
|
|
4
|
+
describe Observed::TaskFactory do
|
|
5
5
|
context 'when the executor not given' do
|
|
6
6
|
it 'fails to initialize' do
|
|
7
|
-
expect { Observed::
|
|
7
|
+
expect { Observed::TaskFactory.new() }.to raise_error
|
|
8
8
|
end
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
context 'when a logger given' do
|
|
12
12
|
it 'may prefer the given logger over the default one' do
|
|
13
|
-
Observed::
|
|
13
|
+
Observed::TaskFactory.new(executor: mock('executor'), logger: ::Logger.new(STDERR))
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
end
|
|
@@ -1,46 +1,46 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
|
-
require 'observed/
|
|
2
|
+
require 'observed/task'
|
|
3
3
|
|
|
4
|
-
describe Observed::
|
|
4
|
+
describe Observed::MutableTask do
|
|
5
5
|
let(:factory) {
|
|
6
|
-
Observed::
|
|
6
|
+
Observed::TaskFactory.new(:executor => Observed::BlockingExecutor.new)
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
it 'yields the given block' do
|
|
10
10
|
yielded = nil
|
|
11
|
-
|
|
11
|
+
task = factory.mutable_task { |data|
|
|
12
12
|
data
|
|
13
13
|
}
|
|
14
|
-
|
|
14
|
+
task.now({a:1}, {b:2}) do |data, options|
|
|
15
15
|
yielded = [data, options]
|
|
16
16
|
end
|
|
17
17
|
expect(yielded).to eq([{a:1}, {b:2}])
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
it 'executes the
|
|
20
|
+
it 'executes the task regardless of whether or not a block is given' do
|
|
21
21
|
executed = nil
|
|
22
|
-
|
|
22
|
+
task = factory.mutable_task { |data, options|
|
|
23
23
|
executed = [data, options]
|
|
24
24
|
data
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
task.now({a:1}, {b:2})
|
|
27
27
|
expect(executed).to eq([{a:1}, {b:2}])
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
describe Observed::
|
|
31
|
+
describe Observed::ParallelTask do
|
|
32
32
|
let(:factory) {
|
|
33
|
-
Observed::
|
|
33
|
+
Observed::TaskFactory.new(:executor => Observed::BlockingExecutor.new)
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
it 'yields the given block' do
|
|
37
|
-
|
|
37
|
+
task1 = factory.task { |data, |
|
|
38
38
|
data.merge(c:3)
|
|
39
39
|
}
|
|
40
|
-
|
|
40
|
+
task2 = factory.task { |data|
|
|
41
41
|
data.merge(d:4)
|
|
42
42
|
}
|
|
43
|
-
par = Observed::
|
|
43
|
+
par = Observed::ParallelTask.new([task1, task2])
|
|
44
44
|
yielded = []
|
|
45
45
|
par.now({a:1}, {b:2}) do |data, options|
|
|
46
46
|
yielded.push([data, options])
|
|
@@ -48,37 +48,37 @@ describe Observed::ParallelJob do
|
|
|
48
48
|
expect(yielded).to eq([[{a:1,c:3},{b:2}], [{a:1,d:4},{b:2}]])
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
it 'executes the
|
|
51
|
+
it 'executes the task regardless of whether or not a block is given' do
|
|
52
52
|
executed = []
|
|
53
|
-
|
|
53
|
+
task1 = factory.task { |data, options|
|
|
54
54
|
r = data.merge(c:3)
|
|
55
55
|
executed.push([r, options])
|
|
56
56
|
r
|
|
57
57
|
}
|
|
58
|
-
|
|
58
|
+
task2 = factory.task { |data, options|
|
|
59
59
|
r = data.merge(d:4)
|
|
60
60
|
executed.push([r, options])
|
|
61
61
|
r
|
|
62
62
|
}
|
|
63
|
-
par = Observed::
|
|
63
|
+
par = Observed::ParallelTask.new([task1, task2])
|
|
64
64
|
par.now({a:1}, {b:2})
|
|
65
65
|
expect(executed).to eq([[{a:1,c:3},{b:2}], [{a:1,d:4},{b:2}]])
|
|
66
66
|
end
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
-
describe Observed::
|
|
69
|
+
describe Observed::SequenceTask do
|
|
70
70
|
let(:factory) {
|
|
71
|
-
Observed::
|
|
71
|
+
Observed::TaskFactory.new(:executor => Observed::BlockingExecutor.new)
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
it 'yields the given block' do
|
|
75
|
-
|
|
75
|
+
task1 = factory.task { |data|
|
|
76
76
|
data.merge(c:3)
|
|
77
77
|
}
|
|
78
|
-
|
|
78
|
+
task2 = factory.task { |data|
|
|
79
79
|
data.merge(d:4)
|
|
80
80
|
}
|
|
81
|
-
seq = Observed::
|
|
81
|
+
seq = Observed::SequenceTask.new(task1, task2)
|
|
82
82
|
yielded = []
|
|
83
83
|
seq.now({a:1}, {b:2}) do |data, options|
|
|
84
84
|
yielded.push([data, options])
|
|
@@ -86,82 +86,82 @@ describe Observed::SequenceJob do
|
|
|
86
86
|
expect(yielded).to eq([[{a:1,c:3,d:4},{b:2}]])
|
|
87
87
|
end
|
|
88
88
|
|
|
89
|
-
it 'executes the
|
|
89
|
+
it 'executes the task regardless of whether or not a block is given' do
|
|
90
90
|
executed = []
|
|
91
|
-
|
|
91
|
+
task1 = factory.task { |data, options|
|
|
92
92
|
r = data.merge(c:3)
|
|
93
93
|
executed.push([r, options])
|
|
94
94
|
r
|
|
95
95
|
}
|
|
96
|
-
|
|
96
|
+
task2 = factory.task { |data, options|
|
|
97
97
|
r = data.merge(d:4)
|
|
98
98
|
executed.push([r, options])
|
|
99
99
|
r
|
|
100
100
|
}
|
|
101
|
-
seq = Observed::
|
|
101
|
+
seq = Observed::SequenceTask.new(task1, task2)
|
|
102
102
|
seq.now({a:1}, {b:2})
|
|
103
103
|
expect(executed).to eq([[{a:1,c:3},{b:2}], [{a:1,c:3,d:4},{b:2}]])
|
|
104
104
|
end
|
|
105
105
|
end
|
|
106
106
|
|
|
107
|
-
describe Observed::
|
|
107
|
+
describe Observed::Task do
|
|
108
108
|
context 'in simple use cases' do
|
|
109
109
|
let(:factory) {
|
|
110
|
-
Observed::
|
|
110
|
+
Observed::TaskFactory.new(:executor => Observed::BlockingExecutor.new)
|
|
111
111
|
}
|
|
112
112
|
context 'when the options as input are given' do
|
|
113
113
|
it 'propagates the options from the input' do
|
|
114
|
-
|
|
114
|
+
task1 = factory.task { |data, options|
|
|
115
115
|
expect(options).to eq({b:2})
|
|
116
116
|
data
|
|
117
117
|
}
|
|
118
|
-
|
|
118
|
+
task2 = factory.task { |_, options|
|
|
119
119
|
expect(options).to eq({b:2})
|
|
120
120
|
}
|
|
121
|
-
seq =
|
|
121
|
+
seq = task1.then(task2)
|
|
122
122
|
seq.now({a:1}, {b:2})
|
|
123
123
|
end
|
|
124
|
-
it 'allows to override the options from the input in subsequent
|
|
125
|
-
|
|
124
|
+
it 'allows to override the options from the input in subsequent tasks' do
|
|
125
|
+
task1 = factory.task { |data, options|
|
|
126
126
|
expect(options).to eq({b:2})
|
|
127
127
|
[data, {b:3}]
|
|
128
128
|
}
|
|
129
|
-
|
|
129
|
+
task2 = factory.task { |_, options|
|
|
130
130
|
expect(options).to eq({b:3})
|
|
131
131
|
}
|
|
132
|
-
seq =
|
|
132
|
+
seq = task1.then(task2)
|
|
133
133
|
seq.now({a:1}, {b:2})
|
|
134
134
|
end
|
|
135
135
|
end
|
|
136
136
|
context 'when the options as input are not given' do
|
|
137
|
-
it 'provides nil in the block parameter and allows to override it in subsequent
|
|
138
|
-
|
|
137
|
+
it 'provides nil in the block parameter and allows to override it in subsequent tasks' do
|
|
138
|
+
task1 = factory.task { |data, options|
|
|
139
139
|
expect(options).to be_nil
|
|
140
140
|
[data, {b:3}]
|
|
141
141
|
}
|
|
142
|
-
|
|
142
|
+
task2 = factory.task { |_, options|
|
|
143
143
|
expect(options).to eq({b:3})
|
|
144
144
|
}
|
|
145
|
-
seq =
|
|
145
|
+
seq = task1.then(task2)
|
|
146
146
|
seq.now({a:1})
|
|
147
147
|
end
|
|
148
148
|
end
|
|
149
149
|
end
|
|
150
150
|
context 'when used in an immutable way' do
|
|
151
|
-
it 'propagates the resulting data to next
|
|
152
|
-
factory = Observed::
|
|
151
|
+
it 'propagates the resulting data to next tasks' do
|
|
152
|
+
factory = Observed::TaskFactory.new(:executor => Observed::BlockingExecutor.new)
|
|
153
153
|
output = mock('output')
|
|
154
154
|
input_data = { input: 1 }
|
|
155
|
-
a = factory.
|
|
155
|
+
a = factory.task { |data|
|
|
156
156
|
data.merge(a: 2)
|
|
157
157
|
}
|
|
158
|
-
b = factory.
|
|
158
|
+
b = factory.task { |data, options|
|
|
159
159
|
data.merge(b: 3)
|
|
160
160
|
}
|
|
161
|
-
c = factory.
|
|
161
|
+
c = factory.task { |data, options|
|
|
162
162
|
output.write data.merge(c: 4)
|
|
163
163
|
}
|
|
164
|
-
d = factory.
|
|
164
|
+
d = factory.task { |data|
|
|
165
165
|
output.write data.merge(d: 5)
|
|
166
166
|
}
|
|
167
167
|
foo = a.then(b).then(c, d)
|
|
@@ -172,20 +172,20 @@ describe Observed::Job do
|
|
|
172
172
|
end
|
|
173
173
|
|
|
174
174
|
context 'when used in a mutable way' do
|
|
175
|
-
it 'propagates the resulting data to next
|
|
176
|
-
factory = Observed::
|
|
175
|
+
it 'propagates the resulting data to next tasks' do
|
|
176
|
+
factory = Observed::TaskFactory.new(:executor => Observed::BlockingExecutor.new)
|
|
177
177
|
output = mock('output')
|
|
178
178
|
input_data = { input: 1 }
|
|
179
|
-
a = factory.
|
|
179
|
+
a = factory.mutable_task { |data|
|
|
180
180
|
data.merge(a: 2)
|
|
181
181
|
}
|
|
182
|
-
b = factory.
|
|
182
|
+
b = factory.task { |data, options|
|
|
183
183
|
data.merge(b: 3)
|
|
184
184
|
}
|
|
185
|
-
c = factory.
|
|
185
|
+
c = factory.task { |data, options|
|
|
186
186
|
output.write data.merge(c: 4)
|
|
187
187
|
}
|
|
188
|
-
d = factory.
|
|
188
|
+
d = factory.task { |data|
|
|
189
189
|
output.write data.merge(d: 5)
|
|
190
190
|
}
|
|
191
191
|
a.then(b).then(c, d)
|
|
@@ -199,22 +199,22 @@ describe Observed::Job do
|
|
|
199
199
|
it 'notifies listeners with resulting data' do
|
|
200
200
|
|
|
201
201
|
listener = mock('listener')
|
|
202
|
-
factory = Observed::
|
|
203
|
-
:executor => Observed::
|
|
202
|
+
factory = Observed::TaskFactory.new(
|
|
203
|
+
:executor => Observed::BlockingExecutor.new,
|
|
204
204
|
:listener => listener
|
|
205
205
|
)
|
|
206
206
|
output = mock('output')
|
|
207
207
|
input_data = { input: 1 }
|
|
208
|
-
a = factory.
|
|
208
|
+
a = factory.task { |data|
|
|
209
209
|
data.merge(a: 2)
|
|
210
210
|
}
|
|
211
|
-
b = factory.
|
|
211
|
+
b = factory.task { |data, options|
|
|
212
212
|
data.merge(b: 3)
|
|
213
213
|
}
|
|
214
|
-
c = factory.
|
|
214
|
+
c = factory.task { |data, options|
|
|
215
215
|
output.write data.merge(c: 4)
|
|
216
216
|
}
|
|
217
|
-
d = factory.
|
|
217
|
+
d = factory.task { |data|
|
|
218
218
|
output.write data.merge(d: 5)
|
|
219
219
|
}
|
|
220
220
|
foo = a.then(b).then(c, d)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: observed
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.0.
|
|
4
|
+
version: 0.2.0.rc2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- KUOKA Yusuke
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2014-01-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -176,6 +176,7 @@ files:
|
|
|
176
176
|
- lib/observed.rb
|
|
177
177
|
- lib/observed/application.rb
|
|
178
178
|
- lib/observed/application/oneshot.rb
|
|
179
|
+
- lib/observed/basic_event_bus.rb
|
|
179
180
|
- lib/observed/builtin_plugins.rb
|
|
180
181
|
- lib/observed/builtin_plugins/file.rb
|
|
181
182
|
- lib/observed/builtin_plugins/stdout.rb
|
|
@@ -187,14 +188,12 @@ files:
|
|
|
187
188
|
- lib/observed/default.rb
|
|
188
189
|
- lib/observed/default/observer.rb
|
|
189
190
|
- lib/observed/event_bus.rb
|
|
190
|
-
- lib/observed/execution_job_factory.rb
|
|
191
191
|
- lib/observed/hash.rb
|
|
192
192
|
- lib/observed/hash/builder.rb
|
|
193
193
|
- lib/observed/hash/fetcher.rb
|
|
194
194
|
- lib/observed/hash/key_path_encoding.rb
|
|
195
|
-
- lib/observed/job.rb
|
|
196
|
-
- lib/observed/jobbed_event_bus.rb
|
|
197
195
|
- lib/observed/logging.rb
|
|
196
|
+
- lib/observed/observed_task_factory.rb
|
|
198
197
|
- lib/observed/observer.rb
|
|
199
198
|
- lib/observed/observer_helpers/timer.rb
|
|
200
199
|
- lib/observed/pluggable.rb
|
|
@@ -202,6 +201,7 @@ files:
|
|
|
202
201
|
- lib/observed/reporter/regexp_matching.rb
|
|
203
202
|
- lib/observed/reporter/report_formatting.rb
|
|
204
203
|
- lib/observed/system.rb
|
|
204
|
+
- lib/observed/task.rb
|
|
205
205
|
- lib/observed/translator.rb
|
|
206
206
|
- lib/observed/version.rb
|
|
207
207
|
- observed.gemspec
|
|
@@ -259,13 +259,13 @@ files:
|
|
|
259
259
|
- plugins/observed-shell/Gemfile
|
|
260
260
|
- plugins/observed-shell/lib/observed/shell.rb
|
|
261
261
|
- run-integration-tests
|
|
262
|
+
- spec/basic_event_bus_spec.rb
|
|
262
263
|
- spec/builtin_plugins/file_spec.rb
|
|
263
264
|
- spec/builtin_plugins/stdout_spec.rb
|
|
264
265
|
- spec/config_builder_spec.rb
|
|
265
266
|
- spec/config_dsl_spec.rb
|
|
266
267
|
- spec/configurable_spec.rb
|
|
267
268
|
- spec/event_bus_spec.rb
|
|
268
|
-
- spec/execution_job_factory_spec.rb
|
|
269
269
|
- spec/fixtures/configure_by_conf/foo_plugin.rb
|
|
270
270
|
- spec/fixtures/configure_by_conf/observed.conf
|
|
271
271
|
- spec/fixtures/configure_by_conf_dot_d/foo_plugin.rb
|
|
@@ -275,16 +275,16 @@ files:
|
|
|
275
275
|
- spec/hash/builder_spec.rb
|
|
276
276
|
- spec/hash/fetcher_spec.rb
|
|
277
277
|
- spec/input_helpers/timer_spec.rb
|
|
278
|
-
- spec/job_factory_spec.rb
|
|
279
|
-
- spec/job_spec.rb
|
|
280
|
-
- spec/jobbed_event_bus_spec.rb
|
|
281
278
|
- spec/observed_spec.rb
|
|
279
|
+
- spec/observed_task_factory_spec.rb
|
|
282
280
|
- spec/observer_helpers/timer_spec.rb
|
|
283
281
|
- spec/observer_spec.rb
|
|
284
282
|
- spec/oneshot_spec.rb
|
|
285
283
|
- spec/reporter_spec.rb
|
|
286
284
|
- spec/spec_helper.rb
|
|
287
285
|
- spec/system_spec.rb
|
|
286
|
+
- spec/task_factory_spec.rb
|
|
287
|
+
- spec/task_spec.rb
|
|
288
288
|
homepage: ''
|
|
289
289
|
licenses:
|
|
290
290
|
- MIT
|
|
@@ -314,13 +314,13 @@ test_files:
|
|
|
314
314
|
- features/oneshot.feature
|
|
315
315
|
- features/support/env.rb
|
|
316
316
|
- features/test_in_single_ruby_source.feature
|
|
317
|
+
- spec/basic_event_bus_spec.rb
|
|
317
318
|
- spec/builtin_plugins/file_spec.rb
|
|
318
319
|
- spec/builtin_plugins/stdout_spec.rb
|
|
319
320
|
- spec/config_builder_spec.rb
|
|
320
321
|
- spec/config_dsl_spec.rb
|
|
321
322
|
- spec/configurable_spec.rb
|
|
322
323
|
- spec/event_bus_spec.rb
|
|
323
|
-
- spec/execution_job_factory_spec.rb
|
|
324
324
|
- spec/fixtures/configure_by_conf/foo_plugin.rb
|
|
325
325
|
- spec/fixtures/configure_by_conf/observed.conf
|
|
326
326
|
- spec/fixtures/configure_by_conf_dot_d/foo_plugin.rb
|
|
@@ -330,13 +330,13 @@ test_files:
|
|
|
330
330
|
- spec/hash/builder_spec.rb
|
|
331
331
|
- spec/hash/fetcher_spec.rb
|
|
332
332
|
- spec/input_helpers/timer_spec.rb
|
|
333
|
-
- spec/job_factory_spec.rb
|
|
334
|
-
- spec/job_spec.rb
|
|
335
|
-
- spec/jobbed_event_bus_spec.rb
|
|
336
333
|
- spec/observed_spec.rb
|
|
334
|
+
- spec/observed_task_factory_spec.rb
|
|
337
335
|
- spec/observer_helpers/timer_spec.rb
|
|
338
336
|
- spec/observer_spec.rb
|
|
339
337
|
- spec/oneshot_spec.rb
|
|
340
338
|
- spec/reporter_spec.rb
|
|
341
339
|
- spec/spec_helper.rb
|
|
342
340
|
- spec/system_spec.rb
|
|
341
|
+
- spec/task_factory_spec.rb
|
|
342
|
+
- spec/task_spec.rb
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
require 'thread'
|
|
2
|
-
require 'observed/event_bus'
|
|
3
|
-
|
|
4
|
-
module Observed
|
|
5
|
-
class JobbedEventBus
|
|
6
|
-
def initialize(args={})
|
|
7
|
-
@bus = Observed::EventBus.new
|
|
8
|
-
@receives = {}
|
|
9
|
-
@job_factory = args[:job_factory] || fail("The parameter :job_factory is missing in args(#{args}")
|
|
10
|
-
@mutex = ::Mutex.new
|
|
11
|
-
end
|
|
12
|
-
def pipe_to_emit(tag)
|
|
13
|
-
@job_factory.job { |*params|
|
|
14
|
-
self.emit(tag, *params)
|
|
15
|
-
params
|
|
16
|
-
}
|
|
17
|
-
end
|
|
18
|
-
def emit(tag, *params)
|
|
19
|
-
@bus.emit tag, *params
|
|
20
|
-
end
|
|
21
|
-
def receive(pattern)
|
|
22
|
-
job = @job_factory.mutable_job {|data, options|
|
|
23
|
-
[data, options]
|
|
24
|
-
}
|
|
25
|
-
@bus.on_receive(pattern) do |*params|
|
|
26
|
-
@mutex.synchronize do
|
|
27
|
-
job.now(*params)
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
job
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
require 'observed/job'
|
|
4
|
-
require 'observed/jobbed_event_bus'
|
|
5
|
-
|
|
6
|
-
describe Observed::JobbedEventBus do
|
|
7
|
-
let(:out) {
|
|
8
|
-
mock('out')
|
|
9
|
-
}
|
|
10
|
-
let(:factory) {
|
|
11
|
-
executor = Observed::BlockingJobExecutor.new
|
|
12
|
-
Observed::JobFactory.new(executor: executor)
|
|
13
|
-
}
|
|
14
|
-
let(:the_job) {
|
|
15
|
-
factory.job { |data, options|
|
|
16
|
-
out.write data, options
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
let(:bus) {
|
|
20
|
-
Observed::JobbedEventBus.new(job_factory: factory)
|
|
21
|
-
}
|
|
22
|
-
it 'should invoke jobs when the corresponding events are emitted' do
|
|
23
|
-
bus.emit('foo')
|
|
24
|
-
bus.receive(/^bar$/).then(the_job)
|
|
25
|
-
bus.emit('baz')
|
|
26
|
-
out.expects(:write).with({a:1}, {b:2})
|
|
27
|
-
bus.emit('bar', {a:1}, {b:2})
|
|
28
|
-
bus.emit('blah')
|
|
29
|
-
end
|
|
30
|
-
it 'should return the job to emit events' do
|
|
31
|
-
bus.pipe_to_emit('foo').now
|
|
32
|
-
bus.receive(/^bar$/).then(the_job)
|
|
33
|
-
bus.pipe_to_emit('baz').now
|
|
34
|
-
out.expects(:write).with({a:1}, {b:2})
|
|
35
|
-
bus.pipe_to_emit('bar').now({a:1}, {b:2})
|
|
36
|
-
bus.pipe_to_emit('blah').now
|
|
37
|
-
end
|
|
38
|
-
end
|