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 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