alephant-sequencer 2.0.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 87eb4dd20f752ece22dbe6b54764419a159454f5
4
- data.tar.gz: 11216e816528c7446d3bb79e8929f1128cdea1db
3
+ metadata.gz: 4af417788a323d36227f7e705f0537eacf11894e
4
+ data.tar.gz: a498b323f2816d4ba5e3aff2d33a7335baa9c908
5
5
  SHA512:
6
- metadata.gz: 0a8bfa3ac07eda7b55546155dafb1000e26e18612d57604fc1f1cd2703edf1fe9bbca98c040b137322bd5ad7dfd3e8de48f79915cfd33187325abd3bea3832d3
7
- data.tar.gz: 98837d665ded03582bf974cf48404e3c610cfc0e5c83955205f22156f119029d1be4a109fcac622c67a741784eec438abb61113d74bd22da5c19072795acf740
6
+ metadata.gz: 109acfd366f1111097bc8df61a5420d51874449a76bd3ba022b9c32e8b83232bc71f494979549a1bdf45b1707cadbe36043229f9637e9dcfa39ce3d183745352
7
+ data.tar.gz: 4de01f944436280b032af57ecb72ca623cc2753ec0b481cdf88fbcf56c9be5452bb10ddec2699a6e2b56b25385a12897b2b2cb49a828e4614881f019081397c4
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
2
+ lib = File.expand_path("../lib", __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'alephant/sequencer/version'
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 'aws-sdk', '~> 1.0'
32
- spec.add_runtime_dependency 'alephant-logger'
33
- spec.add_runtime_dependency 'alephant-support'
34
- spec.add_runtime_dependency 'jsonpath'
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 'jsonpath'
2
- require 'alephant/logger'
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, id, sequence_path, keep_all = true)
10
+ def initialize(sequence_table, opts = {})
11
11
  @sequence_table = sequence_table
12
12
 
13
- @keep_all = keep_all
13
+ @cache = opts[:cache]
14
+ @keep_all = opts[:keep_all]
15
+ @ident = opts[:id]
14
16
  @exists = exists?
15
- @jsonpath = sequence_path
16
- @ident = id
17
+ @jsonpath = opts[:jsonpath]
17
18
  logger.info(
18
19
  "event" => "SequencerInitialized",
19
20
  "sequenceTable" => sequence_table,
20
- "jsonPath" => sequence_path,
21
- "id" => 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 || @sequence_table.sequence_exists(ident)
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
- @sequence_table.sequence_for(key)
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)
@@ -1,5 +1,5 @@
1
1
  module Alephant
2
2
  module Sequencer
3
- VERSION = "2.0.1"
3
+ VERSION = "3.0.0"
4
4
  end
5
5
  end
@@ -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, ident, jsonpath = nil, keep_all = true)
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], ident, jsonpath, keep_all)
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
@@ -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
- describe ".create(table_name, ident, jsonpath)" do
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
- Alephant::Sequencer::SequenceTable
10
- .any_instance
11
- .stub(:create)
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
- subject.create(:table_name, ident, jsonpath)
15
- ).to be_a Alephant::Sequencer::Sequencer
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
- def sequence_table
24
- table = double()
25
- table.stub(:create)
26
- table.stub(:sequence_exists)
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
- subject = Alephant::Sequencer::Sequencer.new(sequence_table, ident, jsonpath)
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(subject.jsonpath).to eq(jsonpath)
38
- expect(subject.ident).to eq(ident)
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(msg, &block)" do
44
- let(:message) do
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.should_not_receive(:called).with(message)
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.should_receive(:called)
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
- subject = Alephant::Sequencer::Sequencer.new(sequence_table, ident, jsonpath)
74
- subject.validate(message, &a_proc)
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
- Alephant::Sequencer::Sequencer
80
- .any_instance
81
- .stub(:get_last_seen)
82
- .and_return(nil)
83
-
84
- Alephant::Sequencer::Sequencer
85
- .stub(:sequence_id_from)
86
- .and_return(stubbed_seen_high)
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(msg, last_seen_id)" do
90
- Alephant::Sequencer::Sequencer
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
- subject = Alephant::Sequencer::Sequencer.new(sequence_table, ident, jsonpath)
96
- subject.validate(message, &a_proc)
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
- Alephant::Sequencer::Sequencer
103
- .any_instance
104
- .stub(:get_last_seen)
105
- .and_return(stubbed_last_seen)
106
-
107
- Alephant::Sequencer::Sequencer
108
- .stub(:sequence_id_from)
109
- .and_return(stubbed_last_seen)
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
- Alephant::Sequencer::Sequencer
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
- subject = Alephant::Sequencer::Sequencer.new(sequence_table, ident, jsonpath)
118
- subject.validate(message, &a_proc)
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
- Alephant::Sequencer::Sequencer
125
- .any_instance
126
- .stub(:get_last_seen)
127
- .and_return(stubbed_last_seen)
128
-
129
- Alephant::Sequencer::Sequencer
130
- .any_instance
131
- .stub(:sequence_id_from)
132
- .and_return(stubbed_seen_low)
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(msg, last_seen_id)" do
136
- Alephant::Sequencer::Sequencer
137
- .any_instance
138
- .should_not_receive(:set_last_seen)
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
- subject = Alephant::Sequencer::Sequencer.new(sequence_table, ident, jsonpath)
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
- subject = Alephant::Sequencer::Sequencer.new(
148
- sequence_table,
149
- ident,
150
- jsonpath,
151
- keep_all
152
- )
153
- subject.validate(message, &an_uncalled_proc)
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
- Alephant::Sequencer::Sequencer
161
- .any_instance
162
- .stub(:get_last_seen)
163
- .and_return(stubbed_last_seen)
164
-
165
- Alephant::Sequencer::Sequencer
166
- .stub(:sequence_id_from)
167
- .and_return(stubbed_seen_high)
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
- Alephant::Sequencer::Sequencer
172
- .any_instance
173
- .should_receive(:set_last_seen)
174
- .with(message, stubbed_last_seen)
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
- subject = Alephant::Sequencer::Sequencer.new(sequence_table, ident, jsonpath)
177
- subject.validate(message, &a_proc)
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
- table = double()
185
- table.stub(:sequence_exists)
186
- table.stub(:create)
187
- table.should_receive(:sequence_for)
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(data)" do
270
+ describe "#set_last_seen" do
200
271
  before(:each) do
201
- Alephant::Sequencer::Sequencer
202
- .stub(:sequence_id_from)
203
- .and_return(last_seen)
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
- table = double()
208
- table.stub(:sequence_exists)
209
- table.stub(:create)
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
- Alephant::Sequencer::Sequencer
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(data)" do
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?(data, jsonpath)" do
303
+ describe "#sequential?" do
233
304
  before(:each) do
234
- Alephant::Sequencer::Sequencer
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.stub(:body)
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(subject.sequential?(data)).to be
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(subject.sequential?(data)).to be false
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(subject.sequential?(data)).to be
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(subject.sequential?(data)).to be false
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
- table = double()
291
- table.stub(:create)
292
- table.stub(:sequence_exists)
293
- table.should_receive(:truncate!)
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
- subject = Alephant::Sequencer::Sequencer.new(table, ident, jsonpath)
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: 2.0.1
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-01-18 00:00:00.000000000 Z
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