evt-event_source 0.16.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|