evt-consumer 0.0.0.1 → 0.2.0.0

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 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