evt-event_source 0.16.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 +7 -0
- data/lib/event_source.rb +26 -0
- data/lib/event_source/controls.rb +13 -0
- data/lib/event_source/controls/category.rb +23 -0
- data/lib/event_source/controls/event_data.rb +13 -0
- data/lib/event_source/controls/event_data/hash.rb +28 -0
- data/lib/event_source/controls/event_data/metadata.rb +24 -0
- data/lib/event_source/controls/event_data/read.rb +63 -0
- data/lib/event_source/controls/event_data/write.rb +43 -0
- data/lib/event_source/controls/random_value.rb +9 -0
- data/lib/event_source/controls/read.rb +14 -0
- data/lib/event_source/controls/stream.rb +17 -0
- data/lib/event_source/controls/stream_name.rb +12 -0
- data/lib/event_source/controls/time.rb +60 -0
- data/lib/event_source/event_data.rb +17 -0
- data/lib/event_source/event_data/hash.rb +31 -0
- data/lib/event_source/event_data/read.rb +16 -0
- data/lib/event_source/event_data/write.rb +7 -0
- data/lib/event_source/expected_version.rb +11 -0
- data/lib/event_source/iterator.rb +102 -0
- data/lib/event_source/log.rb +9 -0
- data/lib/event_source/no_stream.rb +11 -0
- data/lib/event_source/read.rb +80 -0
- data/lib/event_source/stream.rb +27 -0
- data/lib/event_source/stream_name.rb +18 -0
- data/lib/event_source/write.rb +86 -0
- data/lib/loader.rb +1 -0
- metadata +195 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 12664935f7cfa35ee5910e870576e2ed0a809c29
|
4
|
+
data.tar.gz: a78442d098c88ff2de825b21200494bf5382168e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 05c8ebdaee36dd325583a167d299cd863b32250618a96542465e9fe03a7144a218899a8c8ecd5f59714f1a0c65885b47f44b66edbf6d2707639ed6cfe549d56a
|
7
|
+
data.tar.gz: ee2cb57c601c4ced1642ede255f40d52012698f4d7b47cbbaf1d49bddee30cb9c46397d80dffd584cbfe5a9e48a34e2b3cbc9472a5007cf0cec2adf5088bff8d
|
data/lib/event_source.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'pp'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
require 'casing'
|
5
|
+
require 'identifier/uuid'
|
6
|
+
require 'schema'
|
7
|
+
require 'initializer'; Initializer.activate
|
8
|
+
require 'transform'
|
9
|
+
require 'cycle'
|
10
|
+
require 'virtual'; Virtual.activate
|
11
|
+
require 'async_invocation'
|
12
|
+
|
13
|
+
require 'event_source/expected_version'
|
14
|
+
require 'event_source/no_stream'
|
15
|
+
require 'event_source/stream_name'
|
16
|
+
require 'event_source/stream'
|
17
|
+
require 'event_source/event_data'
|
18
|
+
require 'event_source/event_data/hash'
|
19
|
+
require 'event_source/event_data/write'
|
20
|
+
require 'event_source/event_data/read'
|
21
|
+
|
22
|
+
require 'event_source/log'
|
23
|
+
|
24
|
+
require 'event_source/iterator'
|
25
|
+
require 'event_source/read'
|
26
|
+
require 'event_source/write'
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
require 'event_source/controls/random_value'
|
4
|
+
require 'event_source/controls/time'
|
5
|
+
require 'event_source/controls/category'
|
6
|
+
require 'event_source/controls/stream_name'
|
7
|
+
require 'event_source/controls/stream'
|
8
|
+
require 'event_source/controls/read'
|
9
|
+
require 'event_source/controls/event_data'
|
10
|
+
require 'event_source/controls/event_data/hash'
|
11
|
+
require 'event_source/controls/event_data/metadata'
|
12
|
+
require 'event_source/controls/event_data/write'
|
13
|
+
require 'event_source/controls/event_data/read'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module EventSource
|
2
|
+
module Controls
|
3
|
+
module Category
|
4
|
+
def self.example(category: nil, randomize_category: nil)
|
5
|
+
if randomize_category.nil?
|
6
|
+
if !category.nil?
|
7
|
+
randomize_category = false
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
randomize_category = true if randomize_category.nil?
|
12
|
+
|
13
|
+
category ||= 'test'
|
14
|
+
|
15
|
+
if randomize_category
|
16
|
+
category = "#{category}#{SecureRandom.hex(16)}XX"
|
17
|
+
end
|
18
|
+
|
19
|
+
category
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module EventSource
|
2
|
+
module Controls
|
3
|
+
module EventData
|
4
|
+
module Hash
|
5
|
+
def self.data
|
6
|
+
{
|
7
|
+
some_attribute: 'some value'
|
8
|
+
}
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.example
|
12
|
+
EventSource::EventData::Hash[data]
|
13
|
+
end
|
14
|
+
|
15
|
+
module JSON
|
16
|
+
def self.data(id=nil)
|
17
|
+
data = Hash.data
|
18
|
+
Casing::Camel.(data, symbol_to_string: true)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.text
|
22
|
+
::JSON.generate(data)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module EventSource
|
2
|
+
module Controls
|
3
|
+
module EventData
|
4
|
+
module Metadata
|
5
|
+
def self.data
|
6
|
+
{
|
7
|
+
meta_attribute: RandomValue.example
|
8
|
+
}
|
9
|
+
end
|
10
|
+
|
11
|
+
module JSON
|
12
|
+
def self.data(id=nil)
|
13
|
+
data = Metadata.data
|
14
|
+
Casing::Camel.(data, symbol_to_string: true)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.text
|
18
|
+
data.to_json
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module EventSource
|
2
|
+
module Controls
|
3
|
+
module EventData
|
4
|
+
module Read
|
5
|
+
def self.example(type: nil, data: nil, metadata: nil)
|
6
|
+
type ||= self.type
|
7
|
+
|
8
|
+
if data == :none
|
9
|
+
data = nil
|
10
|
+
else
|
11
|
+
data ||= self.data
|
12
|
+
end
|
13
|
+
|
14
|
+
if metadata == :none
|
15
|
+
metadata = nil
|
16
|
+
else
|
17
|
+
metadata ||= self.metadata
|
18
|
+
end
|
19
|
+
|
20
|
+
event_data = EventSource::EventData::Read.build
|
21
|
+
|
22
|
+
event_data.type = type
|
23
|
+
event_data.data = data
|
24
|
+
event_data.metadata = metadata
|
25
|
+
event_data.position = position
|
26
|
+
event_data.global_position = global_position
|
27
|
+
event_data.time = time
|
28
|
+
event_data.stream_name = stream_name
|
29
|
+
|
30
|
+
event_data
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.type
|
34
|
+
EventData.type
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.data
|
38
|
+
EventData.data
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.metadata
|
42
|
+
EventData::Metadata.data
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.position
|
46
|
+
1
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.global_position
|
50
|
+
111
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.time
|
54
|
+
Time::Raw.example
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.stream_name
|
58
|
+
StreamName.example
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module EventSource
|
2
|
+
module Controls
|
3
|
+
module EventData
|
4
|
+
module Write
|
5
|
+
def self.example(type: nil, data: nil, metadata: nil)
|
6
|
+
type ||= self.type
|
7
|
+
|
8
|
+
if data == :none
|
9
|
+
data = nil
|
10
|
+
else
|
11
|
+
data ||= self.metadata
|
12
|
+
end
|
13
|
+
|
14
|
+
if metadata == :none
|
15
|
+
metadata = nil
|
16
|
+
else
|
17
|
+
metadata ||= self.metadata
|
18
|
+
end
|
19
|
+
|
20
|
+
event_data = EventSource::EventData::Write.build
|
21
|
+
|
22
|
+
event_data.type = type
|
23
|
+
event_data.data = data
|
24
|
+
event_data.metadata = metadata
|
25
|
+
|
26
|
+
event_data
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.type
|
30
|
+
EventData.type
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.data
|
34
|
+
EventData.data
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.metadata
|
38
|
+
EventData::Metadata.data
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module EventSource
|
2
|
+
module Controls
|
3
|
+
module Stream
|
4
|
+
def self.example(stream_name: nil, category: nil, id: nil, randomize_category: nil)
|
5
|
+
stream_name ||= StreamName.example category: category, id: id, randomize_category: randomize_category
|
6
|
+
EventSource::Stream.new stream_name
|
7
|
+
end
|
8
|
+
|
9
|
+
module Category
|
10
|
+
def self.example(category: nil, randomize_category: nil)
|
11
|
+
category ||= Controls::Category.example category: category, randomize_category: randomize_category
|
12
|
+
EventSource::Stream.new category
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module EventSource
|
2
|
+
module Controls
|
3
|
+
module StreamName
|
4
|
+
def self.example(category: nil, id: nil, randomize_category: nil)
|
5
|
+
category ||= Category.example(category: category, randomize_category: randomize_category)
|
6
|
+
id ||= Identifier::UUID.random
|
7
|
+
|
8
|
+
"#{category}-#{id}"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module EventSource
|
2
|
+
module Controls
|
3
|
+
module Time
|
4
|
+
def self.example(time=nil)
|
5
|
+
time ||= Raw.example
|
6
|
+
ISO8601.example(time)
|
7
|
+
end
|
8
|
+
|
9
|
+
module Raw
|
10
|
+
def self.example
|
11
|
+
time = ::Time.parse("Jan 1 00:00:00 UTC 2000")
|
12
|
+
Clock::UTC.now(time)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module ISO8601
|
17
|
+
def self.example(time=nil)
|
18
|
+
time ||= Raw.example
|
19
|
+
Clock::UTC.iso8601(time)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module Processed
|
24
|
+
def self.example(time=nil, offset_milliseconds: nil)
|
25
|
+
time ||= Time::Raw.example
|
26
|
+
time = Raw.example(time, offset_milliseconds: offset_milliseconds)
|
27
|
+
ISO8601.example(time)
|
28
|
+
end
|
29
|
+
|
30
|
+
module Raw
|
31
|
+
def self.example(time=nil, offset_milliseconds: nil)
|
32
|
+
time ||= Time::Raw.example
|
33
|
+
offset_milliseconds ||= 11
|
34
|
+
offset = Rational(offset_milliseconds, 1000)
|
35
|
+
time += offset
|
36
|
+
time
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
module Effective
|
42
|
+
def self.example(time=nil, offset_milliseconds: nil)
|
43
|
+
time ||= Time::Raw.example
|
44
|
+
time = Raw.example(time, offset_milliseconds: offset_milliseconds)
|
45
|
+
ISO8601.example(time)
|
46
|
+
end
|
47
|
+
|
48
|
+
module Raw
|
49
|
+
def self.example(time=nil, offset_milliseconds: nil)
|
50
|
+
time ||= Time::Raw.example
|
51
|
+
offset_milliseconds ||= 1
|
52
|
+
offset = Rational(offset_milliseconds, 1000)
|
53
|
+
time += offset
|
54
|
+
time
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module EventSource
|
2
|
+
module EventData
|
3
|
+
def self.included(cls)
|
4
|
+
cls.class_exec do
|
5
|
+
include Schema::DataStructure
|
6
|
+
|
7
|
+
attribute :type
|
8
|
+
attribute :data
|
9
|
+
attribute :metadata
|
10
|
+
|
11
|
+
def ===(other)
|
12
|
+
type == other
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module EventSource
|
2
|
+
module EventData
|
3
|
+
class Hash < ::Hash
|
4
|
+
module Transformer
|
5
|
+
def self.json
|
6
|
+
JSON
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.instance(raw_data)
|
10
|
+
Hash[raw_data]
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.raw_data(instance)
|
14
|
+
Hash[instance]
|
15
|
+
end
|
16
|
+
|
17
|
+
module JSON
|
18
|
+
def self.write(raw_hash_data)
|
19
|
+
json_formatted_data = Casing::Camel.(raw_hash_data)
|
20
|
+
::JSON.generate(json_formatted_data)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.read(text)
|
24
|
+
json_formatted_data = ::JSON.parse(text, :symbolize_names => true)
|
25
|
+
Casing::Underscore.(json_formatted_data)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module EventSource
|
2
|
+
module EventData
|
3
|
+
class Read
|
4
|
+
include EventData
|
5
|
+
|
6
|
+
attribute :stream_name
|
7
|
+
attribute :position
|
8
|
+
attribute :global_position
|
9
|
+
attribute :time
|
10
|
+
|
11
|
+
def category
|
12
|
+
StreamName.get_category(stream_name)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module EventSource
|
2
|
+
module ExpectedVersion
|
3
|
+
class Error < RuntimeError; end
|
4
|
+
|
5
|
+
def self.canonize(expected_version)
|
6
|
+
return nil if expected_version.nil?
|
7
|
+
return expected_version unless expected_version == NoStream.name
|
8
|
+
NoStream.version
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module EventSource
|
2
|
+
class Iterator
|
3
|
+
include Log::Dependency
|
4
|
+
|
5
|
+
dependency :cycle, Cycle
|
6
|
+
|
7
|
+
attr_accessor :position
|
8
|
+
attr_accessor :batch
|
9
|
+
|
10
|
+
def batch_position
|
11
|
+
@batch_position ||= 0
|
12
|
+
end
|
13
|
+
attr_writer :batch_position
|
14
|
+
|
15
|
+
def stream_offset
|
16
|
+
@stream_offset ||= (position || 0)
|
17
|
+
end
|
18
|
+
attr_writer :stream_offset
|
19
|
+
|
20
|
+
initializer :get, :stream_name
|
21
|
+
|
22
|
+
def self.build(get, stream_name, position: nil, cycle: nil)
|
23
|
+
new(get, stream_name).tap do |instance|
|
24
|
+
instance.position = position
|
25
|
+
Cycle.configure instance, cycle: cycle
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.configure(receiver, get, stream_name, attr_name: nil, position: nil, cycle: nil)
|
30
|
+
attr_name ||= :iterator
|
31
|
+
instance = build(get, stream_name, position: position, cycle: cycle)
|
32
|
+
receiver.public_send "#{attr_name}=", instance
|
33
|
+
end
|
34
|
+
|
35
|
+
def next
|
36
|
+
logger.trace { "Getting next event data (Batch Length: #{batch.nil? ? '<none>' : batch.length}, Batch Position: #{batch_position}, Stream Offset: #{stream_offset})" }
|
37
|
+
|
38
|
+
resupply(batch)
|
39
|
+
|
40
|
+
event_data = batch[batch_position]
|
41
|
+
|
42
|
+
logger.debug { "Finished getting next event data (Batch Length: #{batch.nil? ? '<none>' : batch.length}, Batch Position: #{batch_position}, Stream Offset: #{stream_offset})" }
|
43
|
+
logger.debug(tags: [:data, :event_data]) { "Event Data: #{event_data.pretty_inspect}" }
|
44
|
+
|
45
|
+
advance_positions
|
46
|
+
|
47
|
+
event_data
|
48
|
+
end
|
49
|
+
|
50
|
+
def resupply(batch)
|
51
|
+
logger.trace { "Resupplying batch" }
|
52
|
+
|
53
|
+
if batch.nil?
|
54
|
+
batch_log_text = "Batch: #{batch.inspect}"
|
55
|
+
else
|
56
|
+
batch_log_text = "Batch Length: #{batch.length}"
|
57
|
+
end
|
58
|
+
|
59
|
+
if batch.nil? || batch_position == batch.length
|
60
|
+
logger.debug { "Current batch is depleted (#{batch_log_text}, Batch Position: #{batch_position})" }
|
61
|
+
|
62
|
+
batch = get_batch
|
63
|
+
reset(batch)
|
64
|
+
else
|
65
|
+
logger.debug { "Current batch not depleted (#{batch_log_text}, Batch Position: #{batch_position})" }
|
66
|
+
end
|
67
|
+
|
68
|
+
logger.debug { "Finished resupplying batch" }
|
69
|
+
end
|
70
|
+
|
71
|
+
def reset(batch)
|
72
|
+
logger.trace { "Resetting batch" }
|
73
|
+
|
74
|
+
self.batch = batch
|
75
|
+
self.batch_position = 0
|
76
|
+
|
77
|
+
logger.debug { "Reset batch" }
|
78
|
+
logger.debug(tags: [:data, :batch]) { "Batch: #{batch.pretty_inspect}" }
|
79
|
+
logger.debug(tags: [:data, :batch]) { "Batch Position: #{batch_position.inspect}" }
|
80
|
+
end
|
81
|
+
|
82
|
+
def get_batch
|
83
|
+
logger.trace "Getting batch"
|
84
|
+
|
85
|
+
batch = nil
|
86
|
+
cycle.() do
|
87
|
+
batch = get.(stream_name, position: stream_offset)
|
88
|
+
end
|
89
|
+
|
90
|
+
logger.debug { "Finished getting batch (Count: #{batch.length})" }
|
91
|
+
|
92
|
+
batch
|
93
|
+
end
|
94
|
+
|
95
|
+
def advance_positions
|
96
|
+
logger.trace { "Advancing positions (Batch Position: #{batch_position}, Stream Offset: #{stream_offset})" }
|
97
|
+
self.batch_position += 1
|
98
|
+
self.stream_offset += 1
|
99
|
+
logger.debug { "Advanced positions (Batch Position: #{batch_position}, Stream Offset: #{stream_offset})" }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module EventSource
|
2
|
+
module Read
|
3
|
+
def self.included(cls)
|
4
|
+
cls.class_exec do
|
5
|
+
include Log::Dependency
|
6
|
+
|
7
|
+
cls.extend Build
|
8
|
+
cls.extend Call
|
9
|
+
cls.extend Configure
|
10
|
+
|
11
|
+
dependency :iterator, Iterator
|
12
|
+
|
13
|
+
initializer :stream_name
|
14
|
+
|
15
|
+
attr_accessor :get
|
16
|
+
abstract :configure
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Error < RuntimeError; end
|
21
|
+
|
22
|
+
module Build
|
23
|
+
def build(stream_name, position: nil, batch_size: nil, precedence: nil, cycle_delay_milliseconds: nil, cycle_timeout_milliseconds: nil, cycle: nil, session: nil)
|
24
|
+
cycle ||= Cycle.build(delay_milliseconds: cycle_delay_milliseconds, timeout_milliseconds: cycle_timeout_milliseconds)
|
25
|
+
|
26
|
+
new(stream_name).tap do |instance|
|
27
|
+
instance.configure(batch_size: batch_size, precedence: precedence, session: session)
|
28
|
+
Iterator.configure instance, instance.get, stream_name, position: position, cycle: cycle
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module Call
|
34
|
+
def call(stream_name, position: nil, batch_size: nil, precedence: nil, cycle_delay_milliseconds: nil, cycle_timeout_milliseconds: nil, cycle: nil, session: nil, &action)
|
35
|
+
instance = build(stream_name, position: position, batch_size: batch_size, precedence: precedence, cycle_delay_milliseconds: cycle_delay_milliseconds, cycle_timeout_milliseconds: cycle_timeout_milliseconds, cycle: cycle, session: session)
|
36
|
+
instance.(&action)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module Configure
|
41
|
+
def configure(receiver, stream_name, attr_name: nil, position: nil, batch_size: nil, precedence: nil, cycle_delay_milliseconds: nil, cycle_timeout_milliseconds: nil, cycle: nil, session: nil)
|
42
|
+
attr_name ||= :read
|
43
|
+
instance = build(stream_name, position: position, batch_size: batch_size, precedence: precedence, cycle_delay_milliseconds: cycle_delay_milliseconds, cycle_timeout_milliseconds: cycle_timeout_milliseconds, cycle: cycle, session: session)
|
44
|
+
receiver.public_send "#{attr_name}=", instance
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def call(&action)
|
49
|
+
logger.trace { "Reading (Stream Name: #{stream_name})" }
|
50
|
+
|
51
|
+
if action.nil?
|
52
|
+
error_message = "Reader must be actuated with a block"
|
53
|
+
logger.error error_message
|
54
|
+
raise Error, error_message
|
55
|
+
end
|
56
|
+
|
57
|
+
enumerate_event_data(&action)
|
58
|
+
|
59
|
+
logger.info { "Reading completed (Stream Name: #{stream_name})" }
|
60
|
+
|
61
|
+
return AsyncInvocation::Incorrect
|
62
|
+
end
|
63
|
+
|
64
|
+
def enumerate_event_data(&action)
|
65
|
+
logger.trace { "Enumerating (Stream Name: #{stream_name})" }
|
66
|
+
|
67
|
+
event_data = nil
|
68
|
+
|
69
|
+
loop do
|
70
|
+
event_data = iterator.next
|
71
|
+
|
72
|
+
break if event_data.nil?
|
73
|
+
|
74
|
+
action.(event_data)
|
75
|
+
end
|
76
|
+
|
77
|
+
logger.debug { "Enumerated (Stream Name: #{stream_name})" }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module EventSource
|
2
|
+
class Stream
|
3
|
+
initializer :name
|
4
|
+
|
5
|
+
def self.get_type(name)
|
6
|
+
subtype = name.split(':').last.split('-').first
|
7
|
+
|
8
|
+
if name.start_with?(subtype)
|
9
|
+
return :stream
|
10
|
+
else
|
11
|
+
return subtype.to_sym
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def type
|
16
|
+
@type ||= self.class.get_type(name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def category
|
20
|
+
@category ||= StreamName.get_category(name)
|
21
|
+
end
|
22
|
+
|
23
|
+
def category?
|
24
|
+
@is_category ||= !name.include?('-')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module EventSource
|
2
|
+
module StreamName
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def stream_name(category_name, id)
|
6
|
+
"#{category_name}-#{id}"
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.get_id(stream_name)
|
10
|
+
id = stream_name.partition('-')[2]
|
11
|
+
id.empty? ? nil : id
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.get_category(stream_name)
|
15
|
+
stream_name.split('-')[0]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module EventSource
|
2
|
+
module Write
|
3
|
+
def self.included(cls)
|
4
|
+
cls.class_exec do
|
5
|
+
include Log::Dependency
|
6
|
+
|
7
|
+
cls.extend Build
|
8
|
+
cls.extend Call
|
9
|
+
cls.extend Configure
|
10
|
+
|
11
|
+
dependency :put
|
12
|
+
|
13
|
+
abstract :configure
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module Build
|
18
|
+
def build(session: nil)
|
19
|
+
instance = new
|
20
|
+
instance.configure(session: session)
|
21
|
+
instance
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module Configure
|
26
|
+
def configure(receiver, session: nil, attr_name: nil)
|
27
|
+
attr_name ||= :write
|
28
|
+
instance = build(session: session)
|
29
|
+
receiver.public_send "#{attr_name}=", instance
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module Call
|
34
|
+
def call(event_data, stream_name, expected_version: nil, session: nil)
|
35
|
+
instance = build(session: session)
|
36
|
+
instance.(event_data, stream_name, expected_version: expected_version)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def call(event_data, stream_name, expected_version: nil)
|
41
|
+
logger.trace { "Writing event data (Stream Name: #{stream_name}, Expected Version: #{expected_version.inspect})" }
|
42
|
+
logger.trace(tags: [:data, :event_data]) { event_data.pretty_inspect }
|
43
|
+
|
44
|
+
batch = Array(event_data)
|
45
|
+
position = write_batch(batch, stream_name, expected_version: expected_version)
|
46
|
+
|
47
|
+
logger.info { "Wrote event data (Stream Name: #{stream_name}, Expected Version: #{expected_version.inspect})" }
|
48
|
+
logger.info(tags: [:data, :event_data]) { event_data.pretty_inspect }
|
49
|
+
|
50
|
+
position
|
51
|
+
end
|
52
|
+
|
53
|
+
def write_batch(batch, stream_name, expected_version: nil)
|
54
|
+
logger.trace { "Writing batch (Stream Name: #{stream_name}, Number of Events: #{batch.length}, Expected Version: #{expected_version.inspect})" }
|
55
|
+
|
56
|
+
unless expected_version.nil?
|
57
|
+
expected_version = ExpectedVersion.canonize(expected_version)
|
58
|
+
end
|
59
|
+
|
60
|
+
last_position = nil
|
61
|
+
put.session.transaction do
|
62
|
+
batch.each do |event_data|
|
63
|
+
last_position = write(event_data, stream_name, expected_version: expected_version)
|
64
|
+
|
65
|
+
unless expected_version.nil?
|
66
|
+
expected_version += 1
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
logger.debug { "Wrote batch (Stream Name: #{stream_name}, Number of Events: #{batch.length}, Expected Version: #{expected_version.inspect})" }
|
72
|
+
|
73
|
+
last_position
|
74
|
+
end
|
75
|
+
|
76
|
+
def write(event_data, stream_name, expected_version: nil)
|
77
|
+
logger.trace { "Writing event data (Stream Name: #{stream_name}, Type: #{event_data.type}, Expected Version: #{expected_version.inspect})" }
|
78
|
+
logger.trace(tags: [:data, :event_data]) { event_data.pretty_inspect }
|
79
|
+
|
80
|
+
put.(event_data, stream_name, expected_version: expected_version).tap do
|
81
|
+
logger.debug { "Wrote event data (Stream Name: #{stream_name}, Type: #{event_data.type}, Expected Version: #{expected_version.inspect})" }
|
82
|
+
logger.debug(tags: [:data, :event_data]) { event_data.pretty_inspect }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/loader.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
event_source.rb
|
metadata
ADDED
@@ -0,0 +1,195 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: evt-event_source
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.16.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- The Eventide Project
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-12-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: evt-casing
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: evt-schema
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: evt-initializer
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: evt-identifier-uuid
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: evt-transform
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: evt-virtual
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: evt-cycle
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: evt-async_invocation
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: ntl-test_bench
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
description: " "
|
140
|
+
email: opensource@eventide-project.org
|
141
|
+
executables: []
|
142
|
+
extensions: []
|
143
|
+
extra_rdoc_files: []
|
144
|
+
files:
|
145
|
+
- lib/event_source.rb
|
146
|
+
- lib/event_source/controls.rb
|
147
|
+
- lib/event_source/controls/category.rb
|
148
|
+
- lib/event_source/controls/event_data.rb
|
149
|
+
- lib/event_source/controls/event_data/hash.rb
|
150
|
+
- lib/event_source/controls/event_data/metadata.rb
|
151
|
+
- lib/event_source/controls/event_data/read.rb
|
152
|
+
- lib/event_source/controls/event_data/write.rb
|
153
|
+
- lib/event_source/controls/random_value.rb
|
154
|
+
- lib/event_source/controls/read.rb
|
155
|
+
- lib/event_source/controls/stream.rb
|
156
|
+
- lib/event_source/controls/stream_name.rb
|
157
|
+
- lib/event_source/controls/time.rb
|
158
|
+
- lib/event_source/event_data.rb
|
159
|
+
- lib/event_source/event_data/hash.rb
|
160
|
+
- lib/event_source/event_data/read.rb
|
161
|
+
- lib/event_source/event_data/write.rb
|
162
|
+
- lib/event_source/expected_version.rb
|
163
|
+
- lib/event_source/iterator.rb
|
164
|
+
- lib/event_source/log.rb
|
165
|
+
- lib/event_source/no_stream.rb
|
166
|
+
- lib/event_source/read.rb
|
167
|
+
- lib/event_source/stream.rb
|
168
|
+
- lib/event_source/stream_name.rb
|
169
|
+
- lib/event_source/write.rb
|
170
|
+
- lib/loader.rb
|
171
|
+
homepage: https://github.com/eventide-project/event-source
|
172
|
+
licenses:
|
173
|
+
- MIT
|
174
|
+
metadata: {}
|
175
|
+
post_install_message:
|
176
|
+
rdoc_options: []
|
177
|
+
require_paths:
|
178
|
+
- lib
|
179
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
180
|
+
requirements:
|
181
|
+
- - ">="
|
182
|
+
- !ruby/object:Gem::Version
|
183
|
+
version: 2.3.3
|
184
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
185
|
+
requirements:
|
186
|
+
- - ">="
|
187
|
+
- !ruby/object:Gem::Version
|
188
|
+
version: '0'
|
189
|
+
requirements: []
|
190
|
+
rubyforge_project:
|
191
|
+
rubygems_version: 2.5.2
|
192
|
+
signing_key:
|
193
|
+
specification_version: 4
|
194
|
+
summary: Common primitives for event source clients
|
195
|
+
test_files: []
|