eventus 0.2.0 → 0.3.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.
- data/.gitignore +1 -0
- data/Guardfile +1 -1
- data/lib/eventus/aggregate_root.rb +2 -2
- data/lib/eventus/dispatchers/synchronous.rb +19 -0
- data/lib/eventus/dispatchers.rb +5 -0
- data/lib/eventus/errors.rb +1 -0
- data/lib/eventus/persistence/in_memory.rb +20 -3
- data/lib/eventus/persistence/kyotocabinet.rb +44 -6
- data/lib/eventus/stream.rb +14 -6
- data/lib/eventus/version.rb +1 -1
- data/lib/eventus.rb +12 -1
- data/spec/dispatchers/synchronous_spec.rb +15 -0
- data/spec/persistence/in_memory_spec.rb +32 -16
- data/spec/persistence/kyotocabinet_spec.rb +43 -26
- data/spec/spec_helper.rb +15 -0
- data/spec/stream_spec.rb +18 -4
- metadata +8 -7
- data/lib/eventus/store.rb +0 -12
- data/spec/store_spec.rb +0 -22
data/.gitignore
CHANGED
data/Guardfile
CHANGED
@@ -3,7 +3,7 @@ module Eventus
|
|
3
3
|
module ClassMethods
|
4
4
|
def find(id)
|
5
5
|
instance = self.new
|
6
|
-
stream = Eventus::Stream.new(id, persistence)
|
6
|
+
stream = Eventus::Stream.new(id, persistence, Eventus.dispatcher)
|
7
7
|
instance.populate(stream)
|
8
8
|
instance
|
9
9
|
end
|
@@ -36,7 +36,7 @@ module Eventus
|
|
36
36
|
method_name = "apply_#{name}"
|
37
37
|
self.send method_name, body if self.respond_to?(method_name)
|
38
38
|
|
39
|
-
@stream.add(
|
39
|
+
@stream.add(name, body) if is_new
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Eventus
|
2
|
+
module Dispatchers
|
3
|
+
class Synchronous
|
4
|
+
attr_accessor :action
|
5
|
+
|
6
|
+
def initialize(persistence, &block)
|
7
|
+
@persistence = persistence
|
8
|
+
@action = block || lambda {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def dispatch(events)
|
12
|
+
events.each do |e|
|
13
|
+
@action.call(e)
|
14
|
+
@persistence.mark_dispatched e
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/eventus/errors.rb
CHANGED
@@ -8,11 +8,11 @@ module Eventus
|
|
8
8
|
@mutex = Mutex.new
|
9
9
|
end
|
10
10
|
|
11
|
-
def commit(
|
11
|
+
def commit(events)
|
12
12
|
@mutex.synchronize do
|
13
13
|
pending = {}
|
14
|
-
events.
|
15
|
-
key = build_key(
|
14
|
+
events.each do |event|
|
15
|
+
key = build_key(event['sid'], event['sequence'])
|
16
16
|
raise Eventus::ConcurrencyError if @store.include? key
|
17
17
|
value = @serializer.serialize(event)
|
18
18
|
pending[key] = value
|
@@ -34,6 +34,23 @@ module Eventus
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
+
def load_undispatched
|
38
|
+
@mutex.synchronize do
|
39
|
+
@store.map { |k,v| @serializer.deserialize(v) }
|
40
|
+
.reject { |e| e['dispatched'] || e[:dispatched] }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def mark_dispatched(stream_id, sequence)
|
45
|
+
key = build_key(stream_id, sequence)
|
46
|
+
value = @store[key]
|
47
|
+
return unless value
|
48
|
+
event = @serializer.deserialize(value)
|
49
|
+
event['dispatched'] = true
|
50
|
+
obj = @serializer.serialize(event)
|
51
|
+
@store[key] = obj
|
52
|
+
end
|
53
|
+
|
37
54
|
def build_key(id, index)
|
38
55
|
id + ("_%07d" % index)
|
39
56
|
end
|
@@ -6,17 +6,21 @@ module Eventus
|
|
6
6
|
|
7
7
|
def initialize(options = {})
|
8
8
|
@db = ::KyotoCabinet::DB::new
|
9
|
-
@
|
10
|
-
@serializer = options.
|
9
|
+
@queue = ::KyotoCabinet::DB::new
|
10
|
+
@serializer = options.delete(:serializer) || Eventus::Serializers::Marshal
|
11
|
+
queue_con = build_connection(:path => options.delete(:queue_path) || '*')
|
12
|
+
con = build_connection(options)
|
13
|
+
raise Eventus::ConnectionError unless @db.open(con) && @queue.open(queue_con)
|
11
14
|
end
|
12
15
|
|
13
|
-
def commit(
|
14
|
-
pid = pack_hex(id)
|
16
|
+
def commit(events)
|
15
17
|
@db.transaction do
|
16
|
-
events.
|
17
|
-
|
18
|
+
events.each do |event, index|
|
19
|
+
pid = pack_hex(event['sid'])
|
20
|
+
key = build_key(pid, event['sequence'])
|
18
21
|
value = @serializer.serialize(event)
|
19
22
|
raise Eventus::ConcurrencyError unless @db.add(key,value)
|
23
|
+
@queue.set(key, "")
|
20
24
|
end
|
21
25
|
end
|
22
26
|
end
|
@@ -33,6 +37,22 @@ module Eventus
|
|
33
37
|
@db.get_bulk(keys, false).values.map { |obj| @serializer.deserialize(obj) }
|
34
38
|
end
|
35
39
|
|
40
|
+
def load_undispatched
|
41
|
+
events = []
|
42
|
+
@queue.each_key do |key|
|
43
|
+
value = @db.get(key[0])
|
44
|
+
next unless value
|
45
|
+
obj = @serializer.deserialize(value)
|
46
|
+
events << obj
|
47
|
+
end
|
48
|
+
events
|
49
|
+
end
|
50
|
+
|
51
|
+
def mark_dispatched(stream_id, sequence)
|
52
|
+
key = build_key(pack_hex(stream_id), sequence)
|
53
|
+
@queue.remove(key)
|
54
|
+
end
|
55
|
+
|
36
56
|
def pack_hex(id)
|
37
57
|
id.match(/^[0-9a-fA-F]+$/) ? [id].pack('H*') : id
|
38
58
|
end
|
@@ -40,6 +60,24 @@ module Eventus
|
|
40
60
|
def build_key(id, index)
|
41
61
|
id + ("_%07d" % index)
|
42
62
|
end
|
63
|
+
|
64
|
+
def close
|
65
|
+
@db.close
|
66
|
+
@queue.close
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def build_connection(options)
|
72
|
+
opts = {
|
73
|
+
:path => '%', #in-memory tree
|
74
|
+
:opts => :linear
|
75
|
+
}.merge!(options)
|
76
|
+
|
77
|
+
path = opts.delete(:path)
|
78
|
+
|
79
|
+
opts.reduce(path) { |memo, kvp| memo << "##{kvp[0]}=#{kvp[1]}" }
|
80
|
+
end
|
43
81
|
end
|
44
82
|
end
|
45
83
|
end
|
data/lib/eventus/stream.rb
CHANGED
@@ -1,25 +1,33 @@
|
|
1
|
+
require 'time'
|
2
|
+
|
1
3
|
module Eventus
|
2
4
|
class Stream
|
3
5
|
|
4
6
|
attr_reader :id, :committed_events, :uncommitted_events
|
5
7
|
|
6
|
-
def initialize(id, persistence)
|
8
|
+
def initialize(id, persistence, dispatcher)
|
7
9
|
@id = id
|
8
10
|
@persistence = persistence
|
9
11
|
@committed_events = []
|
10
12
|
@uncommitted_events = []
|
13
|
+
@dispatcher = dispatcher
|
11
14
|
load_events @persistence.load(id)
|
12
15
|
end
|
13
16
|
|
14
|
-
def add(
|
15
|
-
@uncommitted_events <<
|
17
|
+
def add(name, body={})
|
18
|
+
@uncommitted_events << {'name' => name, 'body' => body}
|
16
19
|
end
|
17
20
|
|
18
|
-
alias_method :<<, :add
|
19
|
-
|
20
21
|
def commit
|
21
|
-
|
22
|
+
time = Time.now.utc.iso8601
|
23
|
+
@uncommitted_events.each.with_index(version) do |e, i|
|
24
|
+
e['time'] = time
|
25
|
+
e['sid'] = @id
|
26
|
+
e['sequence'] = i
|
27
|
+
end
|
28
|
+
@persistence.commit @uncommitted_events
|
22
29
|
load_events @uncommitted_events
|
30
|
+
@dispatcher.dispatch @uncommitted_events if @dispatcher
|
23
31
|
@uncommitted_events.clear
|
24
32
|
rescue ConcurrencyError => e
|
25
33
|
load_events @persistence.load(id, version + 1)
|
data/lib/eventus/version.rb
CHANGED
data/lib/eventus.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
module Eventus
|
2
2
|
autoload :Serializers, 'eventus/serializers'
|
3
3
|
autoload :AggregateRoot, 'eventus/aggregate_root'
|
4
|
+
autoload :Dispatchers, 'eventus/dispatchers'
|
5
|
+
autoload :Persistence, 'eventus/persistence'
|
6
|
+
autoload :VERSION, 'eventus/version'
|
4
7
|
|
5
8
|
class << self
|
6
9
|
|
@@ -11,7 +14,15 @@ module Eventus
|
|
11
14
|
def persistence=(val)
|
12
15
|
@persistence = val
|
13
16
|
end
|
17
|
+
|
18
|
+
def dispatcher
|
19
|
+
@dispatcher ||= Eventus::Dispatchers::Synchronous.new(persistence)
|
20
|
+
end
|
21
|
+
|
22
|
+
def dispatcher=(val)
|
23
|
+
@dispatcher = val
|
24
|
+
end
|
14
25
|
end
|
15
26
|
end
|
16
27
|
|
17
|
-
%w{
|
28
|
+
%w{stream errors}.each { |r| require "eventus/#{r}" }
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Eventus::Dispatchers::Synchronous do
|
4
|
+
let(:persistence){ stub.as_null_object }
|
5
|
+
let(:dispatcher) { Eventus::Dispatchers::Synchronous.new(persistence) { @hit = true } }
|
6
|
+
|
7
|
+
before do
|
8
|
+
persistence.should_receive(:mark_dispatched)
|
9
|
+
dispatcher.dispatch([stub])
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should invoke block" do
|
13
|
+
@hit.should == true
|
14
|
+
end
|
15
|
+
end
|
@@ -8,10 +8,11 @@ describe Eventus::Persistence::InMemory do
|
|
8
8
|
it "should store complex objects" do
|
9
9
|
id = uuid.generate :compact
|
10
10
|
o = {'a' => 'super', 'complex' => ['object', 'with', {'nested' => ['members', 'galore', 1]}]}
|
11
|
-
|
11
|
+
commit = create_commit(id, 1, o)
|
12
|
+
persistence.commit(commit)
|
12
13
|
|
13
14
|
result = persistence.load id
|
14
|
-
result[0].should ==
|
15
|
+
result[0].should == commit[0]
|
15
16
|
end
|
16
17
|
|
17
18
|
it "should return no events when key not found" do
|
@@ -21,22 +22,22 @@ describe Eventus::Persistence::InMemory do
|
|
21
22
|
|
22
23
|
it "should return events ordered" do
|
23
24
|
id = uuid.generate :compact
|
24
|
-
persistence.commit id, 5,
|
25
|
-
persistence.commit id, 1,
|
26
|
-
persistence.commit id, 3,
|
27
|
-
persistence.commit "other", 1,
|
25
|
+
persistence.commit create_commit(id, 5, "five", "six")
|
26
|
+
persistence.commit create_commit(id, 1, "one", "two")
|
27
|
+
persistence.commit create_commit(id, 3, "three", "four")
|
28
|
+
persistence.commit create_commit("other", 1, "cake", "batter")
|
28
29
|
|
29
30
|
result = persistence.load id
|
30
|
-
result.should == ["one", "two", "three", "four", "five", "six"]
|
31
|
+
result.map{|r| r['body']}.should == ["one", "two", "three", "four", "five", "six"]
|
31
32
|
end
|
32
33
|
|
33
34
|
describe "when events exist" do
|
34
35
|
let(:id) { uuid.generate :compact }
|
35
|
-
let(:events) { (1..20).
|
36
|
+
let(:events) { create_commit(id, 1, *(1..20)).each_with_index {|e,i| e['dispatched'] = i.even? } }
|
36
37
|
before do
|
37
|
-
persistence.commit
|
38
|
-
other_events = (1..60).
|
39
|
-
persistence.commit
|
38
|
+
persistence.commit events
|
39
|
+
other_events = create_commit("other", 1, *(1..60)).each_with_index {|e,i| e['dispatched'] = i.even? }
|
40
|
+
persistence.commit other_events
|
40
41
|
end
|
41
42
|
|
42
43
|
it "should load events" do
|
@@ -44,12 +45,26 @@ describe Eventus::Persistence::InMemory do
|
|
44
45
|
result.length.should == 20
|
45
46
|
end
|
46
47
|
|
48
|
+
it "should load undispatched events" do
|
49
|
+
result = persistence.load_undispatched
|
50
|
+
result.length.should == 40
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should mark an event as dispatched" do
|
54
|
+
result = persistence.load_undispatched[0]
|
55
|
+
persistence.mark_dispatched(result['sid'], result['sequence'])
|
56
|
+
persistence.load_undispatched.include?(result).should be_false
|
57
|
+
end
|
58
|
+
|
47
59
|
it "should throw concurrency exception if the same event number is added" do
|
48
|
-
lambda {persistence.commit id, 3,
|
60
|
+
lambda {persistence.commit create_commit(id, 3, "This is taken")}.should raise_error(Eventus::ConcurrencyError)
|
49
61
|
end
|
50
62
|
|
51
63
|
it "should rollback changes on concurrency error" do
|
52
|
-
|
64
|
+
begin
|
65
|
+
persistence.commit create_commit(id, 3, "first", "second", "third")
|
66
|
+
rescue Eventus::ConcurrencyError
|
67
|
+
end
|
53
68
|
|
54
69
|
result = persistence.load id
|
55
70
|
result.length.should == 20
|
@@ -70,13 +85,14 @@ describe Eventus::Persistence::InMemory do
|
|
70
85
|
it "should use serializer" do
|
71
86
|
input = "original"
|
72
87
|
ser = "i'm serialized!"
|
88
|
+
id = uuid.generate :compact
|
89
|
+
commit = create_commit(id, 1, input)
|
73
90
|
|
74
|
-
serializer.should_receive(:serialize).with(
|
91
|
+
serializer.should_receive(:serialize).with(commit[0]).and_return(ser)
|
75
92
|
serializer.should_receive(:deserialize).with(ser).and_return(input)
|
76
93
|
|
77
|
-
id = uuid.generate :compact
|
78
94
|
|
79
|
-
persistence.commit
|
95
|
+
persistence.commit commit
|
80
96
|
result = persistence.load id
|
81
97
|
result[0].should == input
|
82
98
|
end
|
@@ -1,10 +1,13 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Eventus::Persistence::KyotoCabinet do
|
4
|
-
let(:
|
5
|
-
let(:persistence) { Eventus::Persistence::KyotoCabinet.new(options) }
|
4
|
+
let(:persistence) { @persistence }
|
6
5
|
let(:uuid) { UUID.new }
|
7
6
|
|
7
|
+
before(:all) do
|
8
|
+
@persistence = Eventus::Persistence::KyotoCabinet.new
|
9
|
+
end
|
10
|
+
|
8
11
|
it "should pack keys" do
|
9
12
|
1000.times do
|
10
13
|
key = uuid.generate(:compact)
|
@@ -22,10 +25,11 @@ describe Eventus::Persistence::KyotoCabinet do
|
|
22
25
|
it "should store complex objects" do
|
23
26
|
id = uuid.generate :compact
|
24
27
|
o = {'a' => 'super', 'complex' => ['object', 'with', {'nested' => ['members', 'galore', 1]}]}
|
25
|
-
|
28
|
+
commit = create_commit(id, 1, o)
|
29
|
+
persistence.commit(commit)
|
26
30
|
|
27
31
|
result = persistence.load id
|
28
|
-
result[0].should ==
|
32
|
+
result[0].should == commit[0]
|
29
33
|
end
|
30
34
|
|
31
35
|
it "should return no events when key not found" do
|
@@ -35,64 +39,77 @@ describe Eventus::Persistence::KyotoCabinet do
|
|
35
39
|
|
36
40
|
it "should return events ordered" do
|
37
41
|
id = uuid.generate :compact
|
38
|
-
persistence.commit id, 5,
|
39
|
-
persistence.commit id, 1,
|
40
|
-
persistence.commit id, 3,
|
41
|
-
persistence.commit
|
42
|
+
persistence.commit create_commit(id, 5, "five", "six")
|
43
|
+
persistence.commit create_commit(id, 1, "one", "two")
|
44
|
+
persistence.commit create_commit(id, 3, "three", "four")
|
45
|
+
persistence.commit create_commit(uuid.generate, 1, "cake", "batter")
|
42
46
|
|
43
47
|
result = persistence.load id
|
44
|
-
result.should == ["one", "two", "three", "four", "five", "six"]
|
48
|
+
result.map{|r| r['body']}.should == ["one", "two", "three", "four", "five", "six"]
|
45
49
|
end
|
46
50
|
|
47
51
|
describe "when events exist" do
|
48
52
|
let(:id) { uuid.generate :compact }
|
49
|
-
let(:events) { (1..
|
53
|
+
let(:events) { create_commit(id, 1, *(1..200)) }
|
50
54
|
before do
|
51
|
-
persistence.commit
|
52
|
-
other_events = (1..
|
53
|
-
persistence.commit
|
55
|
+
persistence.commit events
|
56
|
+
other_events = create_commit(uuid.generate(:compact), 1, (1..10))
|
57
|
+
persistence.commit other_events
|
54
58
|
end
|
55
59
|
|
56
60
|
it "should load events" do
|
57
61
|
result = persistence.load id
|
58
|
-
result.length.should ==
|
62
|
+
result.length.should == events.length
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should load undispatched events" do
|
66
|
+
result = persistence.load_undispatched
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should mark an event as dispatched" do
|
70
|
+
result = persistence.load_undispatched[0]
|
71
|
+
persistence.mark_dispatched(result['sid'], result['sequence'])
|
72
|
+
persistence.load_undispatched.include?(result).should be_false
|
59
73
|
end
|
60
74
|
|
61
75
|
it "should throw concurrency exception if the same event number is added" do
|
62
|
-
lambda {persistence.commit id, 3,
|
76
|
+
lambda {persistence.commit create_commit(id, 3, "This is taken")}.should raise_error(Eventus::ConcurrencyError)
|
63
77
|
end
|
64
78
|
|
65
79
|
it "should rollback changes on concurrency error" do
|
66
|
-
|
80
|
+
begin
|
81
|
+
persistence.commit create_commit(id, 3, "first", "second", "third")
|
82
|
+
rescue Eventus::ConcurrencyError
|
83
|
+
end
|
67
84
|
|
68
85
|
result = persistence.load id
|
69
|
-
result.
|
86
|
+
result.should == events
|
70
87
|
end
|
71
88
|
|
72
89
|
it "should load all events from a minimum" do
|
73
90
|
result = persistence.load id, 10
|
74
|
-
result.
|
91
|
+
result.should == events.select {|e| e['sequence'] >= 10}
|
75
92
|
end
|
76
93
|
end
|
77
94
|
|
78
95
|
describe "when serialization is set" do
|
79
96
|
let(:serializer) { stub }
|
80
|
-
|
81
|
-
options[:serializer] = serializer
|
82
|
-
end
|
97
|
+
let(:persistence) { Eventus::Persistence::KyotoCabinet.new(:path => '%', :serializer => serializer) }
|
83
98
|
|
84
99
|
it "should use serializer" do
|
85
|
-
input =
|
86
|
-
ser = "
|
100
|
+
input = {:name => 'event'}
|
101
|
+
ser = "serialized!!"
|
102
|
+
id = uuid.generate :compact
|
103
|
+
commit = create_commit(id, 1, input)
|
87
104
|
|
88
|
-
serializer.should_receive(:serialize).with(
|
105
|
+
serializer.should_receive(:serialize).with(commit[0]).and_return(ser)
|
89
106
|
serializer.should_receive(:deserialize).with(ser).and_return(input)
|
90
107
|
|
91
|
-
id = uuid.generate :compact
|
92
108
|
|
93
|
-
persistence.commit
|
109
|
+
persistence.commit commit
|
94
110
|
result = persistence.load id
|
95
111
|
result[0].should == input
|
96
112
|
end
|
97
113
|
end
|
98
114
|
end
|
115
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -11,3 +11,18 @@ Dir[File.join(File.dirname(__FILE__), 'support', '*.rb')].each { |d| require d }
|
|
11
11
|
RSpec.configure do |config|
|
12
12
|
config.mock_with :rspec
|
13
13
|
end
|
14
|
+
|
15
|
+
def create_commit(id, start, *bodies)
|
16
|
+
if bodies[0].is_a? Range
|
17
|
+
bodies = bodies[0]
|
18
|
+
end
|
19
|
+
bodies.each.with_index(start).map do |b, i|
|
20
|
+
{
|
21
|
+
'name' => 'cereal',
|
22
|
+
'body' => b,
|
23
|
+
'time' => Time.now.utc.iso8601,
|
24
|
+
'sid' => id,
|
25
|
+
'sequence' => i
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
data/spec/stream_spec.rb
CHANGED
@@ -2,8 +2,9 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Eventus::Stream do
|
4
4
|
let(:id) { UUID.generate(:compact) }
|
5
|
-
let(:stream) { Eventus::Stream.new(id, persistence) }
|
5
|
+
let(:stream) { Eventus::Stream.new(id, persistence, dispatcher) }
|
6
6
|
let(:persistence) { stub(:persistence).as_null_object }
|
7
|
+
let(:dispatcher) { stub(:dispatcher).as_null_object }
|
7
8
|
|
8
9
|
it "should use id" do
|
9
10
|
stream.id.should == id
|
@@ -33,8 +34,8 @@ describe Eventus::Stream do
|
|
33
34
|
|
34
35
|
describe "when events added" do
|
35
36
|
before do
|
36
|
-
stream
|
37
|
-
stream.add
|
37
|
+
stream.add "french"
|
38
|
+
stream.add "bread"
|
38
39
|
end
|
39
40
|
|
40
41
|
it "should have uncommitted events" do
|
@@ -44,9 +45,22 @@ describe Eventus::Stream do
|
|
44
45
|
describe "when committed" do
|
45
46
|
before do
|
46
47
|
persistence.should_receive(:commit)
|
48
|
+
dispatcher.should_receive(:dispatch)
|
47
49
|
stream.commit
|
48
50
|
end
|
49
51
|
|
52
|
+
it "should have timestamp on committed events" do
|
53
|
+
stream.committed_events.all?{ |e| e['time'] }.should == true
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should have stream id on committed events" do
|
57
|
+
stream.committed_events.all?{ |e| e['sid'] }.should == true
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should have sequence id on committed events" do
|
61
|
+
stream.committed_events.all?{ |e| e['sequence'] }.should == true
|
62
|
+
end
|
63
|
+
|
50
64
|
it "should have committed events" do
|
51
65
|
stream.version.should == 2
|
52
66
|
end
|
@@ -60,7 +74,7 @@ describe Eventus::Stream do
|
|
60
74
|
describe "when a concurrency error occurs" do
|
61
75
|
before do
|
62
76
|
persistence.should_receive(:commit).and_raise(Eventus::ConcurrencyError)
|
63
|
-
stream
|
77
|
+
stream.add "butter"
|
64
78
|
end
|
65
79
|
|
66
80
|
it "should reraise concurrency error" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eventus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-01-
|
12
|
+
date: 2012-01-13 00:00:00.000000000Z
|
13
13
|
dependencies: []
|
14
14
|
description: An Event Store
|
15
15
|
email:
|
@@ -26,6 +26,8 @@ files:
|
|
26
26
|
- eventus.gemspec
|
27
27
|
- lib/eventus.rb
|
28
28
|
- lib/eventus/aggregate_root.rb
|
29
|
+
- lib/eventus/dispatchers.rb
|
30
|
+
- lib/eventus/dispatchers/synchronous.rb
|
29
31
|
- lib/eventus/errors.rb
|
30
32
|
- lib/eventus/persistence.rb
|
31
33
|
- lib/eventus/persistence/in_memory.rb
|
@@ -33,14 +35,13 @@ files:
|
|
33
35
|
- lib/eventus/serializers.rb
|
34
36
|
- lib/eventus/serializers/marshal.rb
|
35
37
|
- lib/eventus/serializers/msgpack.rb
|
36
|
-
- lib/eventus/store.rb
|
37
38
|
- lib/eventus/stream.rb
|
38
39
|
- lib/eventus/version.rb
|
39
40
|
- spec/aggregate_root_spec.rb
|
41
|
+
- spec/dispatchers/synchronous_spec.rb
|
40
42
|
- spec/persistence/in_memory_spec.rb
|
41
43
|
- spec/persistence/kyotocabinet_spec.rb
|
42
44
|
- spec/spec_helper.rb
|
43
|
-
- spec/store_spec.rb
|
44
45
|
- spec/stream_spec.rb
|
45
46
|
homepage: ''
|
46
47
|
licenses: []
|
@@ -56,7 +57,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
56
57
|
version: '0'
|
57
58
|
segments:
|
58
59
|
- 0
|
59
|
-
hash:
|
60
|
+
hash: 3251011933680470651
|
60
61
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
62
|
none: false
|
62
63
|
requirements:
|
@@ -65,7 +66,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
65
66
|
version: '0'
|
66
67
|
segments:
|
67
68
|
- 0
|
68
|
-
hash:
|
69
|
+
hash: 3251011933680470651
|
69
70
|
requirements: []
|
70
71
|
rubyforge_project: eventus
|
71
72
|
rubygems_version: 1.8.13
|
@@ -74,8 +75,8 @@ specification_version: 3
|
|
74
75
|
summary: Event Store
|
75
76
|
test_files:
|
76
77
|
- spec/aggregate_root_spec.rb
|
78
|
+
- spec/dispatchers/synchronous_spec.rb
|
77
79
|
- spec/persistence/in_memory_spec.rb
|
78
80
|
- spec/persistence/kyotocabinet_spec.rb
|
79
81
|
- spec/spec_helper.rb
|
80
|
-
- spec/store_spec.rb
|
81
82
|
- spec/stream_spec.rb
|
data/lib/eventus/store.rb
DELETED
data/spec/store_spec.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Eventus::Store do
|
4
|
-
let(:persistence) { stub(:persistence).as_null_object }
|
5
|
-
let(:store) { Eventus::Store.new(persistence) }
|
6
|
-
let(:uuid) { UUID.new }
|
7
|
-
let(:stream) { stub(:stream) }
|
8
|
-
|
9
|
-
describe "when opening an event stream" do
|
10
|
-
let(:id) { uuid.generate(:compact) }
|
11
|
-
let(:result) { store.open id }
|
12
|
-
|
13
|
-
it "should request from persistence" do
|
14
|
-
persistence.should_receive(:get_events)
|
15
|
-
result
|
16
|
-
end
|
17
|
-
|
18
|
-
it "should return a stream" do
|
19
|
-
result.should_not be_nil
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|