evt-consumer 0.0.0.1 → 0.2.0.0

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: 1d47d76ca72a1690d983e55f05254d16a7020586
4
- data.tar.gz: 30e729d41f0db67cc91f1703cfa6e18e3c82988d
3
+ metadata.gz: 00b0c73220714ee6fcf3f270b6ad3060fb31b589
4
+ data.tar.gz: ea9bda155670320c05c33e501904bca847d7ebee
5
5
  SHA512:
6
- metadata.gz: c82b2f96df0c299d64e05c264d4a1193fa91768da0b79bdee5ff7fb852bbd0b5e1ed526b5a2c436bb3844b0ddb2a2276a8a36b5a34061d6d45aeec1f8eef3c5b
7
- data.tar.gz: 1e6372fb092c037a2581e4890614a8858f3b71ffddf6a555cb71c6870539e67787b650006baca0d2661fec04bd67a93396bbeee1f00a864f04013749ede15a5f
6
+ metadata.gz: 8915dd125283bc4a281845ef72557f110ec4c63bac950333c516f4c5c77bfee65878de6207928843b14b99f6692cc6b66b98312f252d5c550a2fad4b1a0450ab
7
+ data.tar.gz: 18453c9ca467afbfdd96160cf2f8685e7cc51bc37a4e48c1672b63cda5cc64d0cae9ecb441fe3f28079bcd0247aea6e3ca94029ff619f53fd4f180a78a434433
data/lib/consumer.rb CHANGED
@@ -5,7 +5,24 @@ require 'messaging'
5
5
  require 'log'
6
6
 
7
7
  require 'consumer/log'
8
+ require 'consumer/log_text'
9
+
10
+ require 'consumer/defaults'
11
+
12
+ require 'consumer/handler_registry'
8
13
 
9
- require 'consumer/consumer'
10
14
  require 'consumer/position_store'
15
+ require 'consumer/position_store/substitute'
11
16
  require 'consumer/position_store/telemetry'
17
+
18
+ require 'consumer/dispatch'
19
+ require 'consumer/dispatch/substitute'
20
+
21
+ require 'consumer/subscription'
22
+ require 'consumer/subscription/defaults'
23
+ require 'consumer/subscription/get_batch'
24
+
25
+ require 'consumer/consumer'
26
+ require 'consumer/substitute'
27
+
28
+ require 'consumer/actor'
@@ -0,0 +1,45 @@
1
+ module Consumer
2
+ class Actor
3
+ include ::Actor
4
+ include Log::Dependency
5
+
6
+ initializer :subscription_address
7
+
8
+ dependency :consumer, Consumer
9
+
10
+ def self.build(consumer, subscription)
11
+ instance = new subscription.address
12
+ instance.consumer = consumer
13
+ instance.configure
14
+ instance
15
+ end
16
+
17
+ handle :start do
18
+ request_batch
19
+ end
20
+
21
+ handle Subscription::GetBatch::Reply do |get_batch_reply|
22
+ events = get_batch_reply.batch
23
+
24
+ logger.trace { "Received batch (Events: #{events.count})" }
25
+
26
+ request_batch
27
+
28
+ events.each do |event_data|
29
+ consumer.(event_data)
30
+ end
31
+
32
+ logger.debug { "Batch received (Events: #{events.count})" }
33
+ end
34
+
35
+ def request_batch
36
+ logger.trace { "Requesting batch" }
37
+
38
+ get_batch = Subscription::GetBatch.new address
39
+
40
+ send.(get_batch, subscription_address)
41
+
42
+ logger.debug { "Send batch request" }
43
+ end
44
+ end
45
+ end
@@ -1,18 +1,152 @@
1
1
  module Consumer
2
2
  def self.included(cls)
3
3
  cls.class_exec do
4
- extend StreamMacro
4
+ include Log::Dependency
5
+
6
+ extend Build
7
+ extend Start
8
+
9
+ extend HandleMacro
10
+ extend PositionStoreMacro
11
+
12
+ prepend Configure
13
+
14
+ initializer :stream
15
+
16
+ attr_writer :position_update_interval
17
+
18
+ attr_accessor :cycle_maximum_milliseconds
19
+ attr_accessor :cycle_timeout_milliseconds
20
+
21
+ dependency :dispatch, Dispatch
22
+ dependency :get
23
+ dependency :position_store, PositionStore
24
+ dependency :subscription, Subscription
25
+ end
26
+ end
27
+
28
+ def call(event_data)
29
+ logger.trace { "Dispatching event (#{LogText.event_data event_data})" }
30
+
31
+ dispatch.(event_data)
32
+
33
+ update_position event_data.global_position
34
+
35
+ logger.info { "Event dispatched (#{LogText.event_data event_data})" }
36
+
37
+ rescue => error
38
+ logger.error { "Error raised (Error Class: #{error.class}, Error Message: #{error.message}, #{LogText.event_data event_data})" }
39
+ error_raised error, event_data
40
+ end
41
+
42
+ Virtual::Method.define self, :configure
43
+
44
+ def error_raised(error, _)
45
+ raise error
46
+ end
47
+
48
+ def update_position(position)
49
+ logger.trace { "Updating position (Position: #{position}, Interval: #{position_update_interval})" }
50
+
51
+ if position % position_update_interval == 0
52
+ position_store.put position
53
+
54
+ logger.debug { "Updated position (Position: #{position}, Interval: #{position_update_interval})" }
55
+ else
56
+ logger.debug { "Interval not reached; position not updated (Position: #{position}, Interval: #{position_update_interval})" }
57
+ end
58
+ end
59
+
60
+ module LogText
61
+ def self.event_data(event_data)
62
+ "Stream: #{event_data.stream_name}, Position: #{event_data.position}, GlobalPosition: #{event_data.global_position}, Type: #{event_data.type}"
63
+ end
64
+ end
65
+
66
+ module Configure
67
+ def configure(batch_size: nil, session: nil)
68
+ logger.trace { "Configuring (Batch Size: #{batch_size}, Session: #{session.inspect})" }
69
+
70
+ super
71
+
72
+ position_store_class = self.class.position_store_class
73
+
74
+ unless position_store_class.nil?
75
+ position_store = position_store_class.configure self, stream
76
+
77
+ starting_position = position_store.get
78
+ end
79
+
80
+ subscription = Subscription.configure(
81
+ self,
82
+ stream,
83
+ get,
84
+ position: starting_position,
85
+ cycle_maximum_milliseconds: cycle_maximum_milliseconds,
86
+ cycle_timeout_milliseconds: cycle_timeout_milliseconds
87
+ )
88
+
89
+ Dispatch.configure self, handler_registry: self.class.handler_registry
90
+
91
+ logger.debug { "Configuring (Batch Size: #{batch_size}, Session: #{session.inspect})" }
92
+ end
93
+ end
94
+
95
+ module Build
96
+ def build(stream_name, batch_size: nil, session: nil, cycle_timeout_milliseconds: nil, cycle_maximum_milliseconds: nil)
97
+ stream = EventSource::Stream.canonize stream_name
98
+
99
+ instance = new stream
100
+ instance.cycle_maximum_milliseconds = cycle_maximum_milliseconds
101
+ instance.cycle_timeout_milliseconds = cycle_timeout_milliseconds
102
+ instance.configure batch_size: batch_size, session: session
103
+ instance
104
+ end
105
+ end
106
+
107
+ module Start
108
+ def start(stream_name, **arguments, &probe)
109
+ instance = build stream_name, **arguments
110
+
111
+ _, subscription_thread = ::Actor::Start.(instance.subscription)
112
+
113
+ actor_address = Actor.start instance, instance.subscription
114
+
115
+ probe.(instance, actor_address) if probe
116
+
117
+ AsyncInvocation::Incorrect
118
+ end
119
+ end
120
+
121
+ module HandleMacro
122
+ def handle_macro(handler=nil, &block)
123
+ handler ||= block
124
+
125
+ handler_registry.register handler
126
+ end
127
+ alias_method :handle, :handle_macro
128
+
129
+ def handler_registry
130
+ @handler_registry ||= HandlerRegistry.new
5
131
  end
6
132
  end
7
133
 
8
- module StreamMacro
9
- def stream_macro(stream_name)
10
- stream = EventSource::Stream.new stream_name
134
+ module PositionStoreMacro
135
+ def self.extended(cls)
136
+ cls.singleton_class.class_exec do
137
+ attr_accessor :position_store_class
138
+ end
139
+ end
140
+
141
+ def position_store_macro(position_store_class, update_interval: nil)
142
+ update_interval ||= Defaults.position_update_interval
143
+
144
+ self.position_store_class = position_store_class
11
145
 
12
- define_method :stream do
13
- stream
146
+ define_method :position_update_interval do
147
+ @position_update_interval ||= update_interval
14
148
  end
15
149
  end
16
- alias_method :stream, :stream_macro
150
+ alias_method :position_store, :position_store_macro
17
151
  end
18
152
  end
@@ -1,12 +1,21 @@
1
1
  require 'messaging/controls'
2
2
 
3
3
  require 'consumer/controls/category'
4
+ require 'consumer/controls/cycle'
4
5
  require 'consumer/controls/event_data'
6
+ require 'consumer/controls/event_data/batch'
7
+ require 'consumer/controls/error'
8
+ require 'consumer/controls/get'
9
+ require 'consumer/controls/get/incrementing'
10
+ require 'consumer/controls/handle'
5
11
  require 'consumer/controls/id'
6
12
  require 'consumer/controls/position'
7
13
  require 'consumer/controls/stream'
8
14
  require 'consumer/controls/stream_name'
9
15
 
10
16
  require 'consumer/controls/position_store'
17
+ require 'consumer/controls/position_store/local_file'
18
+ require 'consumer/controls/subscription'
11
19
 
12
20
  require 'consumer/controls/consumer'
21
+ require 'consumer/controls/consumer/incrementing'
@@ -2,13 +2,18 @@ module Consumer
2
2
  module Controls
3
3
  module Consumer
4
4
  def self.example
5
- Example.new
5
+ Example.new Stream.example
6
6
  end
7
7
 
8
8
  class Example
9
9
  include ::Consumer
10
10
 
11
- stream StreamName.example
11
+ handle Handle::Example
12
+ position_store PositionStore::Example
13
+
14
+ def configure(session: nil, batch_size: nil)
15
+ Get::Example.configure self
16
+ end
12
17
  end
13
18
  end
14
19
  end
@@ -0,0 +1,30 @@
1
+ module Consumer
2
+ module Controls
3
+ module Consumer
4
+ class Incrementing
5
+ include ::Consumer
6
+
7
+ def self.logger
8
+ @logger ||= ::Log.get self
9
+ end
10
+
11
+ handle do |event_data|
12
+ logger.info { "Handled event (StreamName: #{event_data.stream_name}, GlobalPosition: #{event_data.global_position})" }
13
+ end
14
+
15
+ handle do |event_data|
16
+ logger.debug { event_data.data.pretty_inspect }
17
+ end
18
+
19
+ position_store PositionStore::LocalFile, update_interval: 10
20
+
21
+ def configure(session: nil)
22
+ sleep_duration = ENV['SLEEP_DURATION'] || 100
23
+ sleep_duration = sleep_duration.to_i
24
+
25
+ Get::Incrementing.configure self, sleep_duration
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,20 @@
1
+ module Consumer
2
+ module Controls
3
+ module Cycle
4
+ def self.example
5
+ ::Cycle.build(
6
+ maximum_milliseconds: maximum_milliseconds,
7
+ timeout_milliseconds: timeout_milliseconds
8
+ )
9
+ end
10
+
11
+ def self.maximum_milliseconds
12
+ 1
13
+ end
14
+
15
+ def self.timeout_milliseconds
16
+ 11
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,11 @@
1
+ module Consumer
2
+ module Controls
3
+ module Error
4
+ def self.example
5
+ Example.new
6
+ end
7
+
8
+ Example = Class.new StandardError
9
+ end
10
+ end
11
+ end
@@ -1,11 +1,13 @@
1
1
  module Consumer
2
2
  module Controls
3
3
  module EventData
4
- def self.example(stream_name: nil, position: nil, global_position: nil)
5
- event_data = EventSource::Controls::EventData::Read.example
4
+ def self.example(stream_name: nil, data: nil, position: nil, global_position: nil)
5
+ global_position ||= position
6
+
7
+ event_data = EventSource::Controls::EventData::Read.example data: data
6
8
  event_data.stream_name = stream_name unless stream_name.nil?
7
9
  event_data.position = position unless position.nil?
8
- event_data.global_position unless global_position.nil?
10
+ event_data.global_position = global_position unless global_position.nil?
9
11
  event_data
10
12
  end
11
13
  end
@@ -0,0 +1,22 @@
1
+ module Consumer
2
+ module Controls
3
+ module EventData
4
+ module Batch
5
+ def self.example(instances: nil, position: nil)
6
+ instances ||= size
7
+ start_position ||= Controls::Position::Global.example
8
+
9
+ instances.times.map do |offset|
10
+ position = start_position + offset
11
+
12
+ EventData.example global_position: position
13
+ end
14
+ end
15
+
16
+ def self.size
17
+ 3
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,41 @@
1
+ module Consumer
2
+ module Controls
3
+ module Get
4
+ def self.example
5
+ Example.new
6
+ end
7
+
8
+ class Example
9
+ configure :get
10
+
11
+ def self.build
12
+ new
13
+ end
14
+
15
+ def call(stream_name, position: nil)
16
+ position ||= 0
17
+
18
+ stream = streams.fetch stream_name do
19
+ return nil
20
+ end
21
+
22
+ stream[position]
23
+ end
24
+
25
+ def set_batch(stream_name, batch, position=nil)
26
+ position ||= 0
27
+
28
+ stream = streams[stream_name]
29
+
30
+ stream[position] = batch
31
+ end
32
+
33
+ def streams
34
+ @streams ||= Hash.new do |hash, key|
35
+ hash[key] = {}
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,42 @@
1
+ module Consumer
2
+ module Controls
3
+ module Get
4
+ class Incrementing
5
+ configure :get
6
+
7
+ initializer :sleep_duration
8
+
9
+ def self.build(sleep_duration)
10
+ new sleep_duration
11
+ end
12
+
13
+ def call(stream_name, position: nil)
14
+ position ||= 0
15
+
16
+ sleep Rational(sleep_duration, 1000)
17
+
18
+ 3.times.map do |offset|
19
+ EventData.get(
20
+ stream_name,
21
+ position + offset,
22
+ offset
23
+ )
24
+ end
25
+ end
26
+ end
27
+
28
+ class EventData
29
+ def self.get(stream_name, global_position, position)
30
+ data = { :position => position, :global_position => global_position }
31
+
32
+ Controls::EventData.example(
33
+ stream_name: stream_name,
34
+ data: data,
35
+ global_position: global_position,
36
+ position: position
37
+ )
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,17 @@
1
+ module Consumer
2
+ module Controls
3
+ module Handle
4
+ class Example
5
+ include Messaging::Handle
6
+
7
+ def handle(event_data)
8
+ handled_events << event_data
9
+ end
10
+
11
+ def handled_events
12
+ @handled_events ||= []
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -8,8 +8,12 @@ module Consumer
8
8
  end
9
9
 
10
10
  module Global
11
- def self.example
12
- EventSource::Controls::EventData::Read.global_position
11
+ def self.example(offset: nil)
12
+ offset ||= 0
13
+
14
+ position = EventSource::Controls::EventData::Read.global_position
15
+
16
+ position + offset
13
17
  end
14
18
  end
15
19
  end
@@ -0,0 +1,23 @@
1
+ module Consumer
2
+ module Controls
3
+ module PositionStore
4
+ class LocalFile
5
+ include Consumer::PositionStore
6
+
7
+ def get
8
+ return 0 unless File.exist? path
9
+ text = File.read path
10
+ text.to_i
11
+ end
12
+
13
+ def put(position)
14
+ File.write path, position
15
+ end
16
+
17
+ def path
18
+ 'tmp/control_position_store'
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ module Consumer
2
+ module Controls
3
+ module Subscription
4
+ def self.example(next_batch: nil, batch: nil, position: nil)
5
+ stream = Stream.example
6
+
7
+ get = Get.example
8
+
9
+ unless batch.nil?
10
+ get.set_batch stream.name, batch, position
11
+ end
12
+
13
+ subscription = ::Consumer::Subscription.new stream, get
14
+
15
+ subscription.position = position if position
16
+
17
+ unless next_batch.nil?
18
+ subscription.next_batch = next_batch
19
+ end
20
+
21
+ subscription
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,7 @@
1
+ module Consumer
2
+ module Defaults
3
+ def self.position_update_interval
4
+ 100
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,43 @@
1
+ module Consumer
2
+ class Dispatch
3
+ include Log::Dependency
4
+
5
+ configure :dispatch
6
+
7
+ attr_writer :handler_registry
8
+
9
+ def handler_registry
10
+ @handler_registry ||= HandlerRegistry.new
11
+ end
12
+
13
+ def self.build(handler_registry: nil)
14
+ instance = new
15
+ instance.handler_registry = handler_registry unless handler_registry.nil?
16
+ instance
17
+ end
18
+
19
+ def call(event_data)
20
+ logger.trace { "Dispatching event (#{LogText.event_data event_data})" }
21
+
22
+ handlers = handler_registry.get
23
+
24
+ handlers.each do |handle|
25
+ handle.(event_data)
26
+ end
27
+
28
+ logger.debug { "Event dispatched (#{LogText.event_data event_data}, Handlers Count: #{handlers.count})" }
29
+
30
+ nil
31
+ end
32
+
33
+ def to_proc
34
+ method :call
35
+ end
36
+
37
+ module Assertions
38
+ def handler?(handle)
39
+ handler_registry.registered? handle
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,29 @@
1
+ module Consumer
2
+ class Dispatch
3
+ module Substitute
4
+ def self.build
5
+ Dispatch.new
6
+ end
7
+
8
+ class Dispatch
9
+ def call(event_data)
10
+ dispatched_events << event_data
11
+ end
12
+
13
+ def dispatched_events
14
+ @dispatched_events ||= []
15
+ end
16
+
17
+ def dispatched?(event_data=nil, &block)
18
+ if event_data.nil?
19
+ block ||= proc { true }
20
+ else
21
+ block ||= proc { |e| event_data == e }
22
+ end
23
+
24
+ dispatched_events.any? &block
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,63 @@
1
+ module Consumer
2
+ class HandlerRegistry
3
+ include Log::Dependency
4
+
5
+ configure :handler_registry
6
+
7
+ def register(handler)
8
+ logger.trace { "Registering handler (Handler: #{LogText.handler handler})" }
9
+
10
+ if registered? handler
11
+ error_message = "Handler is already registered (Handler: #{LogText.handler handler})"
12
+ logger.error error_message
13
+ raise Error, error_message
14
+ end
15
+
16
+ if handler.respond_to? :build
17
+ instance = handler.build
18
+ else
19
+ instance = handler
20
+ end
21
+
22
+ entries << instance
23
+
24
+ logger.debug { "Handler registered (Handler: #{LogText.handler handler})" }
25
+
26
+ instance
27
+ end
28
+
29
+ def get
30
+ entries.to_a
31
+ end
32
+
33
+ def registered?(handler)
34
+ entries.any? do |entry|
35
+ return true if handler == entry
36
+
37
+ next if entry.is_a? Proc
38
+
39
+ handler === entry
40
+ end
41
+ end
42
+
43
+ def entries
44
+ @entries ||= Set.new
45
+ end
46
+
47
+ def count
48
+ entries.count
49
+ end
50
+
51
+ module LogText
52
+ def self.handler(handler)
53
+ case handler
54
+ when Module then handler.name
55
+ when Proc then '(proc)'
56
+ else handler.inspect
57
+ end
58
+ end
59
+ end
60
+
61
+ Error = Class.new StandardError
62
+ end
63
+ end
@@ -0,0 +1,7 @@
1
+ module Consumer
2
+ module LogText
3
+ def self.event_data(event_data)
4
+ "Stream: #{event_data.stream_name}, Position: #{event_data.position}, GlobalPosition: #{event_data.global_position}, Type: #{event_data.type}"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,30 @@
1
+ module Consumer
2
+ module PositionStore
3
+ module Substitute
4
+ def self.build
5
+ PositionStore.new
6
+ end
7
+
8
+ class PositionStore
9
+ attr_accessor :get_position
10
+ attr_accessor :put_position
11
+
12
+ def get
13
+ get_position
14
+ end
15
+
16
+ def put(position)
17
+ self.put_position = position
18
+ end
19
+
20
+ def put?(expected_position=nil)
21
+ if expected_position.nil?
22
+ put_position ? true : false
23
+ else
24
+ put_position == expected_position
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,89 @@
1
+ module Consumer
2
+ class Subscription
3
+ include ::Actor
4
+ include Log::Dependency
5
+
6
+ configure :subscription
7
+
8
+ initializer :stream, :get
9
+
10
+ attr_accessor :next_batch
11
+
12
+ attr_writer :position
13
+ def position
14
+ @position ||= 0
15
+ end
16
+
17
+ dependency :cycle, Cycle
18
+
19
+ def self.build(stream, get, position: nil, cycle_maximum_milliseconds: nil, cycle_timeout_milliseconds: nil)
20
+ cycle_maximum_milliseconds ||= Defaults.cycle_maximum_milliseconds
21
+ cycle_timeout_milliseconds ||= Defaults.cycle_timeout_milliseconds
22
+
23
+ instance = new stream, get
24
+
25
+ instance.position = position
26
+
27
+ Cycle.configure(
28
+ instance,
29
+ maximum_milliseconds: cycle_maximum_milliseconds,
30
+ timeout_milliseconds: cycle_timeout_milliseconds
31
+ )
32
+
33
+ instance.configure
34
+ instance
35
+ end
36
+
37
+ handle :start do
38
+ :resupply
39
+ end
40
+
41
+ handle :resupply do
42
+ logger.trace { "Resupplying (StreamName: #{stream.name}, Position: #{position})" }
43
+
44
+ batch = cycle.() do
45
+ get.(stream.name, position: position)
46
+ end
47
+
48
+ if batch.nil? || batch.empty?
49
+ logger.debug { "Did not resupply; no events available (StreamName: #{stream.name}, Position: #{position})" }
50
+
51
+ :resupply
52
+ else
53
+ self.next_batch = batch
54
+
55
+ logger.debug { "Resupplied (StreamName: #{stream.name}, Position: #{position}, Batch Size: #{batch.count})" }
56
+ end
57
+ end
58
+
59
+ handle :get_batch do |get_batch|
60
+ logger.trace { "Batch request received" }
61
+
62
+ if next_batch.nil?
63
+ logger.debug { "Could not fulfill batch request; deferring" }
64
+
65
+ return get_batch
66
+ end
67
+
68
+ batch = reset_next_batch
69
+
70
+ reply_message = get_batch.reply_message batch
71
+
72
+ send.(reply_message, get_batch.reply_address)
73
+
74
+ logger.debug { "Batch request fulfilled; resupplying (Batch Size: #{batch.count})" }
75
+
76
+ :resupply
77
+ end
78
+
79
+ def reset_next_batch
80
+ batch = next_batch
81
+
82
+ self.next_batch = nil
83
+
84
+ self.position = batch.last.global_position + 1
85
+
86
+ batch
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,13 @@
1
+ module Consumer
2
+ class Subscription
3
+ module Defaults
4
+ def self.cycle_maximum_milliseconds
5
+ 100
6
+ end
7
+
8
+ def self.cycle_timeout_milliseconds
9
+ 1000
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ module Consumer
2
+ class Subscription
3
+ GetBatch = Struct.new :reply_address
4
+
5
+ class GetBatch
6
+ include ::Actor::Messaging::Message
7
+
8
+ def reply_message(batch)
9
+ Reply.new batch
10
+ end
11
+
12
+ Reply = Struct.new :batch do
13
+ include ::Actor::Messaging::Message
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,27 @@
1
+ module Consumer
2
+ module Substitute
3
+ def self.build
4
+ Consumer.new
5
+ end
6
+
7
+ class Consumer
8
+ def call(event_data)
9
+ consumed_events << event_data
10
+ end
11
+
12
+ def consumed_events
13
+ @consumed_events ||= []
14
+ end
15
+
16
+ def consumed?(event_data=nil, &block)
17
+ if event_data.nil?
18
+ block ||= proc { true }
19
+ else
20
+ block ||= proc { |e| event_data == e }
21
+ end
22
+
23
+ consumed_events.any? &block
24
+ end
25
+ end
26
+ end
27
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: evt-consumer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0.1
4
+ version: 0.2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - The Eventide Project
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-20 00:00:00.000000000 Z
11
+ date: 2017-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ntl-actor
@@ -73,19 +73,39 @@ extensions: []
73
73
  extra_rdoc_files: []
74
74
  files:
75
75
  - lib/consumer.rb
76
+ - lib/consumer/actor.rb
76
77
  - lib/consumer/consumer.rb
77
78
  - lib/consumer/controls.rb
78
79
  - lib/consumer/controls/category.rb
79
80
  - lib/consumer/controls/consumer.rb
81
+ - lib/consumer/controls/consumer/incrementing.rb
82
+ - lib/consumer/controls/cycle.rb
83
+ - lib/consumer/controls/error.rb
80
84
  - lib/consumer/controls/event_data.rb
85
+ - lib/consumer/controls/event_data/batch.rb
86
+ - lib/consumer/controls/get.rb
87
+ - lib/consumer/controls/get/incrementing.rb
88
+ - lib/consumer/controls/handle.rb
81
89
  - lib/consumer/controls/id.rb
82
90
  - lib/consumer/controls/position.rb
83
91
  - lib/consumer/controls/position_store.rb
92
+ - lib/consumer/controls/position_store/local_file.rb
84
93
  - lib/consumer/controls/stream.rb
85
94
  - lib/consumer/controls/stream_name.rb
95
+ - lib/consumer/controls/subscription.rb
96
+ - lib/consumer/defaults.rb
97
+ - lib/consumer/dispatch.rb
98
+ - lib/consumer/dispatch/substitute.rb
99
+ - lib/consumer/handler_registry.rb
86
100
  - lib/consumer/log.rb
101
+ - lib/consumer/log_text.rb
87
102
  - lib/consumer/position_store.rb
103
+ - lib/consumer/position_store/substitute.rb
88
104
  - lib/consumer/position_store/telemetry.rb
105
+ - lib/consumer/subscription.rb
106
+ - lib/consumer/subscription/defaults.rb
107
+ - lib/consumer/subscription/get_batch.rb
108
+ - lib/consumer/substitute.rb
89
109
  homepage: https://github.com/eventide-project/consumer
90
110
  licenses:
91
111
  - MIT