alephant-sequencer 2.0.1 → 3.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 +4 -4
- data/alephant-sequencer.gemspec +7 -6
- data/lib/alephant/sequencer/sequence_cache.rb +69 -0
- data/lib/alephant/sequencer/sequencer.rb +16 -11
- data/lib/alephant/sequencer/version.rb +1 -1
- data/lib/alephant/sequencer.rb +18 -2
- data/spec/sequencer_spec.rb +222 -142
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4af417788a323d36227f7e705f0537eacf11894e
|
4
|
+
data.tar.gz: a498b323f2816d4ba5e3aff2d33a7335baa9c908
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 109acfd366f1111097bc8df61a5420d51874449a76bd3ba022b9c32e8b83232bc71f494979549a1bdf45b1707cadbe36043229f9637e9dcfa39ce3d183745352
|
7
|
+
data.tar.gz: 4de01f944436280b032af57ecb72ca623cc2753ec0b481cdf88fbcf56c9be5452bb10ddec2699a6e2b56b25385a12897b2b2cb49a828e4614881f019081397c4
|
data/alephant-sequencer.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
lib = File.expand_path(
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
4
|
+
require "alephant/sequencer/version"
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "alephant-sequencer"
|
@@ -28,8 +28,9 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.add_development_dependency "pry-remote"
|
29
29
|
spec.add_development_dependency "pry-nav"
|
30
30
|
|
31
|
-
spec.add_runtime_dependency
|
32
|
-
spec.add_runtime_dependency
|
33
|
-
spec.add_runtime_dependency
|
34
|
-
spec.add_runtime_dependency
|
31
|
+
spec.add_runtime_dependency "aws-sdk", "~> 1.0"
|
32
|
+
spec.add_runtime_dependency "alephant-logger"
|
33
|
+
spec.add_runtime_dependency "alephant-support"
|
34
|
+
spec.add_runtime_dependency "jsonpath"
|
35
|
+
spec.add_runtime_dependency "dalli-elasticache"
|
35
36
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require "dalli-elasticache"
|
2
|
+
require "alephant/logger"
|
3
|
+
|
4
|
+
module Alephant
|
5
|
+
module Sequencer
|
6
|
+
class SequenceCache
|
7
|
+
include Logger
|
8
|
+
|
9
|
+
attr_reader :config
|
10
|
+
|
11
|
+
DEFAULT_TTL = 5
|
12
|
+
|
13
|
+
def initialize(config={})
|
14
|
+
@config = config
|
15
|
+
|
16
|
+
unless config_endpoint.nil?
|
17
|
+
@elasticache ||= ::Dalli::ElastiCache.new(config_endpoint, { :expires_in => ttl })
|
18
|
+
@client ||= @elasticache.client
|
19
|
+
else
|
20
|
+
logger.debug "Alephant::SequenceCache::#initialize: No config endpoint, NullClient used"
|
21
|
+
logger.metric "NoConfigEndpoint"
|
22
|
+
@client = NullClient.new
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def get(key, &block)
|
27
|
+
begin
|
28
|
+
versioned_key = versioned key
|
29
|
+
result = @client.get versioned_key
|
30
|
+
logger.info "Alephant::SequenceCache#get key: #{versioned_key} - #{result ? 'hit' : 'miss'}"
|
31
|
+
logger.metric "GetKeyMiss" unless result
|
32
|
+
result ? result : set(key, block.call)
|
33
|
+
rescue StandardError => e
|
34
|
+
block.call
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def set(key, value, ttl = nil)
|
39
|
+
value.tap { |o| @client.set(versioned(key), o, ttl) }
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def config_endpoint
|
45
|
+
config["elasticache_config_endpoint"]
|
46
|
+
end
|
47
|
+
|
48
|
+
def ttl
|
49
|
+
config["elasticache_ttl"] || DEFAULT_TTL
|
50
|
+
end
|
51
|
+
|
52
|
+
def versioned(key)
|
53
|
+
[key, cache_version].compact.join("_")
|
54
|
+
end
|
55
|
+
|
56
|
+
def cache_version
|
57
|
+
config["elasticache_cache_version"]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class NullClient
|
62
|
+
def get(key); end
|
63
|
+
|
64
|
+
def set(key, value, ttl = nil)
|
65
|
+
value
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -1,24 +1,25 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "jsonpath"
|
2
|
+
require "alephant/logger"
|
3
3
|
|
4
4
|
module Alephant
|
5
5
|
module Sequencer
|
6
6
|
class Sequencer
|
7
7
|
include Logger
|
8
|
-
attr_reader :ident, :jsonpath, :keep_all
|
8
|
+
attr_reader :ident, :jsonpath, :keep_all, :cache
|
9
9
|
|
10
|
-
def initialize(sequence_table,
|
10
|
+
def initialize(sequence_table, opts = {})
|
11
11
|
@sequence_table = sequence_table
|
12
12
|
|
13
|
-
@
|
13
|
+
@cache = opts[:cache]
|
14
|
+
@keep_all = opts[:keep_all]
|
15
|
+
@ident = opts[:id]
|
14
16
|
@exists = exists?
|
15
|
-
@jsonpath =
|
16
|
-
@ident = id
|
17
|
+
@jsonpath = opts[:jsonpath]
|
17
18
|
logger.info(
|
18
19
|
"event" => "SequencerInitialized",
|
19
20
|
"sequenceTable" => sequence_table,
|
20
|
-
"jsonPath" =>
|
21
|
-
"id" =>
|
21
|
+
"jsonPath" => @jsonpath,
|
22
|
+
"id" => @ident,
|
22
23
|
"method" => "#{self.class}#initialize"
|
23
24
|
)
|
24
25
|
end
|
@@ -28,7 +29,9 @@ module Alephant
|
|
28
29
|
end
|
29
30
|
|
30
31
|
def exists?
|
31
|
-
@exists ||
|
32
|
+
@exists || cache.get(ident) do
|
33
|
+
@sequence_table.sequence_exists(ident)
|
34
|
+
end
|
32
35
|
end
|
33
36
|
|
34
37
|
def validate(msg, &block)
|
@@ -75,7 +78,9 @@ module Alephant
|
|
75
78
|
end
|
76
79
|
|
77
80
|
def get_last_seen(key = ident)
|
78
|
-
|
81
|
+
cache.get(key) do
|
82
|
+
@sequence_table.sequence_for(key)
|
83
|
+
end
|
79
84
|
end
|
80
85
|
|
81
86
|
def self.sequence_id_from(msg, path)
|
data/lib/alephant/sequencer.rb
CHANGED
@@ -1,15 +1,31 @@
|
|
1
1
|
require "alephant/sequencer/version"
|
2
2
|
require "alephant/sequencer/sequencer"
|
3
3
|
require "alephant/sequencer/sequence_table"
|
4
|
+
require "alephant/sequencer/sequence_cache"
|
4
5
|
|
5
6
|
module Alephant
|
6
7
|
module Sequencer
|
7
8
|
@@sequence_tables = {}
|
8
9
|
|
9
|
-
def self.create(table_name,
|
10
|
+
def self.create(table_name, opts = {})
|
11
|
+
defaults = {
|
12
|
+
:jsonpath => nil,
|
13
|
+
:keep_all => true,
|
14
|
+
:config => {}
|
15
|
+
}
|
16
|
+
|
17
|
+
opts = defaults.merge(opts).tap do |opts|
|
18
|
+
opts[:cache] = self.cache(opts[:config])
|
19
|
+
end
|
20
|
+
|
10
21
|
@@sequence_tables[table_name] ||= SequenceTable.new(table_name)
|
11
|
-
Sequencer.new(@@sequence_tables[table_name],
|
22
|
+
Sequencer.new(@@sequence_tables[table_name], opts)
|
12
23
|
end
|
13
24
|
|
25
|
+
private
|
26
|
+
|
27
|
+
def self.cache(config)
|
28
|
+
@cache ||= SequenceCache.new(config)
|
29
|
+
end
|
14
30
|
end
|
15
31
|
end
|
data/spec/sequencer_spec.rb
CHANGED
@@ -3,16 +3,51 @@ require "spec_helper"
|
|
3
3
|
describe Alephant::Sequencer do
|
4
4
|
let(:ident) { :ident }
|
5
5
|
let(:jsonpath) { "$.sequence_id" }
|
6
|
-
|
7
|
-
|
6
|
+
let(:sequence_table) { double(Alephant::Sequencer::SequenceTable) }
|
7
|
+
let(:keep_all) { true }
|
8
|
+
let(:config) { { "elasticache_config_endpoint" => "/foo" } }
|
9
|
+
let(:cache) { Alephant::Sequencer::SequenceCache.new(config) }
|
10
|
+
let(:opts) {
|
11
|
+
{
|
12
|
+
:id => ident,
|
13
|
+
:jsonpath => jsonpath,
|
14
|
+
:keep_all => keep_all,
|
15
|
+
:cache => cache
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
describe ".create" do
|
8
20
|
it "should return a Sequencer" do
|
9
|
-
|
10
|
-
|
11
|
-
|
21
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:initialize)
|
22
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:client).and_return(Dalli::Client.new)
|
23
|
+
|
24
|
+
expect_any_instance_of(Alephant::Sequencer::SequenceTable).to receive(:initialize)
|
25
|
+
expect_any_instance_of(Alephant::Sequencer::SequenceTable).to receive(:sequence_exists)
|
26
|
+
|
27
|
+
opts = {
|
28
|
+
:id => ident,
|
29
|
+
:jsonpath => jsonpath,
|
30
|
+
:keep_all => keep_all,
|
31
|
+
:config => config
|
32
|
+
}
|
33
|
+
|
34
|
+
expect(subject.create(:table_name, opts)).to be_a Alephant::Sequencer::Sequencer
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should use default opts if options not provided" do
|
38
|
+
expect_any_instance_of(Alephant::Sequencer::SequenceTable).to receive(:sequence_exists)
|
39
|
+
|
40
|
+
opts = {
|
41
|
+
:id => ident
|
42
|
+
}
|
43
|
+
|
44
|
+
instance = subject.create(:table_name, opts)
|
12
45
|
|
13
|
-
expect(
|
14
|
-
|
15
|
-
).to
|
46
|
+
expect(instance).to be_a Alephant::Sequencer::Sequencer
|
47
|
+
expect(instance.ident).to eq(ident)
|
48
|
+
expect(instance.jsonpath).to eq(nil)
|
49
|
+
expect(instance.keep_all).to eq(true)
|
50
|
+
expect(instance.cache).to be_a(Alephant::Sequencer::SequenceCache)
|
16
51
|
end
|
17
52
|
end
|
18
53
|
|
@@ -20,36 +55,30 @@ describe Alephant::Sequencer do
|
|
20
55
|
let(:data) { double() }
|
21
56
|
let(:last_seen) { 42 }
|
22
57
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
table.stub(:sequence_for)
|
28
|
-
table.stub(:update_sequence_id)
|
29
|
-
table.stub(:truncate!)
|
30
|
-
table
|
31
|
-
end
|
58
|
+
describe "#initialize" do
|
59
|
+
subject (:instance) {
|
60
|
+
described_class.new(sequence_table, opts)
|
61
|
+
}
|
32
62
|
|
33
|
-
describe "#initialize(opts, id)" do
|
34
63
|
it "sets @jsonpath, @ident" do
|
35
|
-
|
64
|
+
expect(sequence_table).to receive(:sequence_exists)
|
65
|
+
|
66
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:initialize)
|
67
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:client).and_return(Dalli::Client.new)
|
36
68
|
|
37
|
-
expect(
|
38
|
-
expect(
|
69
|
+
expect(instance.jsonpath).to eq(jsonpath)
|
70
|
+
expect(instance.ident).to eq(ident)
|
71
|
+
expect(instance.keep_all).to eq(true)
|
39
72
|
end
|
40
73
|
|
41
74
|
end
|
42
75
|
|
43
|
-
describe "#validate
|
44
|
-
let(:message)
|
45
|
-
m = double()
|
46
|
-
m.stub(:body)
|
47
|
-
m
|
48
|
-
end
|
76
|
+
describe "#validate" do
|
77
|
+
let(:message) { double() }
|
49
78
|
|
50
79
|
let(:an_uncalled_proc) do
|
51
80
|
a_block = double()
|
52
|
-
a_block.
|
81
|
+
expect(a_block).to_not receive(:called).with(message)
|
53
82
|
|
54
83
|
Proc.new do |msg|
|
55
84
|
a_block.called(msg)
|
@@ -58,7 +87,7 @@ describe Alephant::Sequencer do
|
|
58
87
|
|
59
88
|
let(:a_proc) do
|
60
89
|
a_block = double()
|
61
|
-
a_block.
|
90
|
+
expect(a_block).to receive(:called)
|
62
91
|
|
63
92
|
Proc.new do
|
64
93
|
a_block.called
|
@@ -69,187 +98,236 @@ describe Alephant::Sequencer do
|
|
69
98
|
let(:stubbed_seen_high) { 3 }
|
70
99
|
let(:stubbed_seen_low) { 1 }
|
71
100
|
|
101
|
+
subject (:instance) {
|
102
|
+
described_class.new(sequence_table, opts)
|
103
|
+
}
|
104
|
+
|
72
105
|
it "should call the passed block" do
|
73
|
-
|
74
|
-
|
106
|
+
expect(sequence_table).to receive(:sequence_exists)
|
107
|
+
expect(sequence_table).to receive(:sequence_for).with(ident)
|
108
|
+
|
109
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:initialize)
|
110
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:client).and_return(Dalli::Client.new)
|
111
|
+
|
112
|
+
expect_any_instance_of(Dalli::Client).to receive(:get).twice
|
113
|
+
expect_any_instance_of(Dalli::Client).to receive(:set).twice
|
114
|
+
|
115
|
+
expect(message).to receive(:body)
|
116
|
+
|
117
|
+
instance.validate(message, &a_proc)
|
75
118
|
end
|
76
119
|
|
77
120
|
context "last_seen_id is nil" do
|
78
121
|
before(:each) do
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
122
|
+
expect_any_instance_of(described_class).to receive(:get_last_seen).and_return(nil)
|
123
|
+
|
124
|
+
expect(described_class).to receive(:sequence_id_from).and_return(stubbed_seen_high)
|
125
|
+
|
126
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:initialize)
|
127
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:client).and_return(Dalli::Client.new)
|
128
|
+
|
129
|
+
expect_any_instance_of(Dalli::Client).to receive(:get)
|
130
|
+
expect_any_instance_of(Dalli::Client).to receive(:set)
|
87
131
|
end
|
88
132
|
|
89
|
-
it "should not call set_last_seen
|
90
|
-
|
91
|
-
.any_instance
|
92
|
-
.should_receive(:set_last_seen)
|
93
|
-
.with(message, nil)
|
133
|
+
it "should not call set_last_seen" do
|
134
|
+
expect_any_instance_of(described_class).to receive(:set_last_seen).with(message, nil)
|
94
135
|
|
95
|
-
|
96
|
-
|
136
|
+
expect(sequence_table).to receive(:sequence_exists)
|
137
|
+
|
138
|
+
instance.validate(message, &a_proc)
|
97
139
|
end
|
98
140
|
end
|
99
141
|
|
100
142
|
context "last_seen_id == sequence_id_from(msg)" do
|
101
143
|
before(:each) do
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
144
|
+
expect_any_instance_of(described_class).to receive(:get_last_seen).and_return(stubbed_last_seen)
|
145
|
+
|
146
|
+
expect(described_class).to receive(:sequence_id_from).and_return(stubbed_last_seen)
|
147
|
+
|
148
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:initialize)
|
149
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:client).and_return(Dalli::Client.new)
|
150
|
+
|
151
|
+
expect_any_instance_of(Dalli::Client).to receive(:get)
|
152
|
+
expect_any_instance_of(Dalli::Client).to receive(:set)
|
110
153
|
end
|
111
154
|
|
112
155
|
it "should not call set_last_seen(msg, last_seen_id)" do
|
113
|
-
|
114
|
-
.any_instance
|
115
|
-
.should_not_receive(:set_last_seen)
|
156
|
+
expect_any_instance_of(described_class).to_not receive(:set_last_seen)
|
116
157
|
|
117
|
-
|
118
|
-
|
158
|
+
expect(sequence_table).to receive(:sequence_exists)
|
159
|
+
|
160
|
+
instance.validate(message, &a_proc)
|
119
161
|
end
|
120
162
|
end
|
121
163
|
|
122
164
|
context "last_seen_id > sequence_id_from(msg)" do
|
123
165
|
before(:each) do
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
166
|
+
expect_any_instance_of(described_class).to receive(:get_last_seen).and_return(stubbed_last_seen)
|
167
|
+
|
168
|
+
expect(described_class).to receive(:sequence_id_from).and_return(stubbed_seen_low)
|
169
|
+
|
170
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:initialize)
|
171
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:client).and_return(Dalli::Client.new)
|
172
|
+
|
173
|
+
expect_any_instance_of(Dalli::Client).to receive(:get)
|
174
|
+
expect_any_instance_of(Dalli::Client).to receive(:set)
|
133
175
|
end
|
134
176
|
|
135
|
-
it "should not call set_last_seen
|
136
|
-
|
137
|
-
|
138
|
-
|
177
|
+
it "should not call set_last_seen" do
|
178
|
+
expect_any_instance_of(described_class).to_not receive(:set_last_seen)
|
179
|
+
|
180
|
+
expect(sequence_table).to receive(:sequence_exists)
|
139
181
|
|
140
|
-
|
141
|
-
subject.validate(message, &a_proc)
|
182
|
+
instance.validate(message, &a_proc)
|
142
183
|
end
|
143
184
|
|
144
185
|
context "keep_all is false" do
|
145
186
|
let(:keep_all) { false }
|
187
|
+
|
146
188
|
it "should not call the passed block with msg" do
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
189
|
+
expect(sequence_table).to receive(:sequence_exists)
|
190
|
+
|
191
|
+
opts = {
|
192
|
+
:id => ident,
|
193
|
+
:jsonpath => jsonpath,
|
194
|
+
:keep_all => keep_all,
|
195
|
+
:cache => cache
|
196
|
+
}
|
197
|
+
|
198
|
+
instance = described_class.new(sequence_table, opts)
|
199
|
+
instance.validate(message, &an_uncalled_proc)
|
154
200
|
end
|
155
201
|
end
|
156
202
|
end
|
157
203
|
|
158
204
|
context "last_seen_id < sequence_id_from(msg)" do
|
159
205
|
before(:each) do
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
206
|
+
expect_any_instance_of(described_class).to receive(:get_last_seen).and_return(stubbed_last_seen)
|
207
|
+
|
208
|
+
expect(described_class).to receive(:sequence_id_from).and_return(stubbed_seen_high)
|
209
|
+
|
210
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:initialize)
|
211
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:client).and_return(Dalli::Client.new)
|
212
|
+
|
213
|
+
expect_any_instance_of(Dalli::Client).to receive(:get)
|
214
|
+
expect_any_instance_of(Dalli::Client).to receive(:set)
|
168
215
|
end
|
169
216
|
|
170
217
|
it "should call set_last_seen(msg, last_seen_id)" do
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
218
|
+
expect_any_instance_of(described_class).to receive(:set_last_seen).with(message, stubbed_last_seen)
|
219
|
+
|
220
|
+
expect(sequence_table).to receive(:sequence_exists)
|
221
|
+
|
222
|
+
instance.validate(message, &a_proc)
|
223
|
+
end
|
224
|
+
end
|
175
225
|
|
176
|
-
|
177
|
-
|
226
|
+
context "values already in cache" do
|
227
|
+
before(:each) do
|
228
|
+
expect(message).to receive(:body).and_return("sequence_id" => 5)
|
229
|
+
|
230
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:initialize)
|
231
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:client).and_return(Dalli::Client.new)
|
232
|
+
|
233
|
+
expect_any_instance_of(Dalli::Client).to receive(:get).twice.with("ident").and_return(stubbed_last_seen)
|
234
|
+
expect_any_instance_of(Dalli::Client).to_not receive(:set)
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should read values from cache and not database" do
|
238
|
+
expect(sequence_table).to_not receive(:sequence_for)
|
239
|
+
expect(sequence_table).to_not receive(:sequence_exists)
|
240
|
+
|
241
|
+
expect_any_instance_of(described_class).to receive(:set_last_seen).with(message, stubbed_last_seen)
|
242
|
+
|
243
|
+
instance.validate(message, &a_proc)
|
178
244
|
end
|
179
245
|
end
|
180
246
|
end
|
181
247
|
|
182
248
|
describe "#get_last_seen" do
|
249
|
+
subject (:instance) {
|
250
|
+
described_class.new(sequence_table, opts)
|
251
|
+
}
|
252
|
+
|
183
253
|
it "returns sequence_table.sequence_for(ident)" do
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
254
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:initialize)
|
255
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:client).and_return(Dalli::Client.new)
|
256
|
+
|
257
|
+
expect_any_instance_of(Dalli::Client).to receive(:get).twice
|
258
|
+
expect_any_instance_of(Dalli::Client).to receive(:set).twice
|
259
|
+
|
260
|
+
expect(sequence_table).to receive(:sequence_exists)
|
261
|
+
|
262
|
+
expect(sequence_table).to receive(:sequence_for)
|
188
263
|
.with(ident)
|
189
264
|
.and_return(:expected_value)
|
190
265
|
|
191
|
-
expect(
|
192
|
-
Alephant::Sequencer::Sequencer
|
193
|
-
.new(table, ident, jsonpath)
|
194
|
-
.get_last_seen
|
195
|
-
).to eq(:expected_value)
|
266
|
+
expect(instance.get_last_seen).to eq(:expected_value)
|
196
267
|
end
|
197
268
|
end
|
198
269
|
|
199
|
-
describe "#set_last_seen
|
270
|
+
describe "#set_last_seen" do
|
200
271
|
before(:each) do
|
201
|
-
|
202
|
-
|
203
|
-
|
272
|
+
expect(described_class).to receive(:sequence_id_from).and_return(last_seen)
|
273
|
+
|
274
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:initialize)
|
275
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:client).and_return(Dalli::Client.new)
|
276
|
+
|
277
|
+
expect_any_instance_of(Dalli::Client).to receive(:get).twice
|
278
|
+
expect_any_instance_of(Dalli::Client).to receive(:set).twice
|
204
279
|
end
|
205
280
|
|
281
|
+
subject (:instance) {
|
282
|
+
described_class.new(sequence_table, opts)
|
283
|
+
}
|
284
|
+
|
206
285
|
it "calls update_sequence_id(ident, last_seen)" do
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
table.stub(:sequence_for)
|
211
|
-
table.should_receive(:update_sequence_id)
|
286
|
+
expect(sequence_table).to receive(:sequence_exists).twice
|
287
|
+
|
288
|
+
expect(sequence_table).to receive(:update_sequence_id)
|
212
289
|
.with(ident, last_seen, nil)
|
213
290
|
|
214
|
-
|
215
|
-
.new(table, ident, jsonpath)
|
216
|
-
.set_last_seen(data)
|
291
|
+
instance.set_last_seen(data)
|
217
292
|
end
|
218
293
|
end
|
219
294
|
|
220
|
-
describe ".sequence_id_from
|
221
|
-
subject { Alephant::Sequencer::Sequencer }
|
222
|
-
|
295
|
+
describe ".sequence_id_from" do
|
223
296
|
it "should return the id described by the set jsonpath" do
|
224
297
|
msg = Struct.new(:body).new("set_sequence_id" => 1)
|
225
298
|
|
226
|
-
expect(
|
227
|
-
subject.sequence_id_from(msg, "$.set_sequence_id")
|
228
|
-
).to eq(1)
|
299
|
+
expect(described_class.sequence_id_from(msg, "$.set_sequence_id")).to eq(1)
|
229
300
|
end
|
230
301
|
end
|
231
302
|
|
232
|
-
describe "#sequential?
|
303
|
+
describe "#sequential?" do
|
233
304
|
before(:each) do
|
234
|
-
|
235
|
-
.any_instance
|
236
|
-
.stub(:get_last_seen)
|
237
|
-
.and_return(1)
|
305
|
+
expect_any_instance_of(described_class).to receive(:get_last_seen).and_return(1)
|
238
306
|
|
239
|
-
data.
|
307
|
+
expect(data).to receive(:body)
|
240
308
|
.and_return("sequence_id" => id_value)
|
309
|
+
|
310
|
+
expect(sequence_table).to receive(:sequence_exists)
|
311
|
+
|
312
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:initialize)
|
313
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:client).and_return(Dalli::Client.new)
|
314
|
+
|
315
|
+
expect_any_instance_of(Dalli::Client).to receive(:get)
|
316
|
+
expect_any_instance_of(Dalli::Client).to receive(:set)
|
241
317
|
end
|
242
318
|
|
319
|
+
subject (:instance) {
|
320
|
+
described_class.new(sequence_table, opts)
|
321
|
+
}
|
322
|
+
|
243
323
|
context "jsonpath = '$.sequence_id'" do
|
244
324
|
let(:jsonpath) { "$.sequence_id" }
|
245
325
|
|
246
|
-
subject { Alephant::Sequencer::Sequencer.new(sequence_table, :ident, jsonpath) }
|
247
|
-
|
248
326
|
context "sequential" do
|
249
327
|
let(:id_value) { 2 }
|
250
328
|
|
251
329
|
it "is true" do
|
252
|
-
expect(
|
330
|
+
expect(instance.sequential?(data)).to be
|
253
331
|
end
|
254
332
|
end
|
255
333
|
|
@@ -257,7 +335,7 @@ describe Alephant::Sequencer do
|
|
257
335
|
let(:id_value) { 0 }
|
258
336
|
|
259
337
|
it "is false" do
|
260
|
-
expect(
|
338
|
+
expect(instance.sequential?(data)).to be false
|
261
339
|
end
|
262
340
|
end
|
263
341
|
end
|
@@ -265,13 +343,11 @@ describe Alephant::Sequencer do
|
|
265
343
|
context "jsonpath = nil" do
|
266
344
|
let(:jsonpath) { "$.sequence_id" }
|
267
345
|
|
268
|
-
subject { Alephant::Sequencer::Sequencer.new(sequence_table, :ident, jsonpath) }
|
269
|
-
|
270
346
|
context "sequential" do
|
271
347
|
let(:id_value) { 2 }
|
272
348
|
|
273
349
|
it "is true" do
|
274
|
-
expect(
|
350
|
+
expect(instance.sequential?(data)).to be
|
275
351
|
end
|
276
352
|
end
|
277
353
|
|
@@ -279,21 +355,25 @@ describe Alephant::Sequencer do
|
|
279
355
|
let(:id_value) { 0 }
|
280
356
|
|
281
357
|
it "is false" do
|
282
|
-
expect(
|
358
|
+
expect(instance.sequential?(data)).to be false
|
283
359
|
end
|
284
360
|
end
|
285
361
|
end
|
286
362
|
end
|
287
363
|
|
288
364
|
describe "#truncate!" do
|
365
|
+
subject (:instance) {
|
366
|
+
described_class.new(sequence_table, opts)
|
367
|
+
}
|
368
|
+
|
289
369
|
it "verify SequenceTable#truncate!" do
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
370
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:initialize)
|
371
|
+
expect_any_instance_of(Dalli::ElastiCache).to receive(:client).and_return(Dalli::Client.new)
|
372
|
+
|
373
|
+
expect(sequence_table).to receive(:sequence_exists)
|
374
|
+
expect(sequence_table).to receive(:truncate!)
|
294
375
|
|
295
|
-
|
296
|
-
subject.truncate!
|
376
|
+
instance.truncate!
|
297
377
|
end
|
298
378
|
end
|
299
379
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alephant-sequencer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- BBC News
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -206,6 +206,20 @@ dependencies:
|
|
206
206
|
- - '>='
|
207
207
|
- !ruby/object:Gem::Version
|
208
208
|
version: '0'
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
requirement: !ruby/object:Gem::Requirement
|
211
|
+
requirements:
|
212
|
+
- - '>='
|
213
|
+
- !ruby/object:Gem::Version
|
214
|
+
version: '0'
|
215
|
+
name: dalli-elasticache
|
216
|
+
prerelease: false
|
217
|
+
type: :runtime
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - '>='
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '0'
|
209
223
|
description:
|
210
224
|
email:
|
211
225
|
- FutureMediaNewsRubyGems@bbc.co.uk
|
@@ -223,6 +237,7 @@ files:
|
|
223
237
|
- Rakefile
|
224
238
|
- alephant-sequencer.gemspec
|
225
239
|
- lib/alephant/sequencer.rb
|
240
|
+
- lib/alephant/sequencer/sequence_cache.rb
|
226
241
|
- lib/alephant/sequencer/sequence_table.rb
|
227
242
|
- lib/alephant/sequencer/sequencer.rb
|
228
243
|
- lib/alephant/sequencer/version.rb
|