alephant-broker 3.14.0 → 3.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +22 -9
  3. data/README.md +35 -6
  4. data/alephant-broker.gemspec +3 -2
  5. data/lib/alephant/broker/cache.rb +1 -0
  6. data/lib/alephant/broker/cache/cached_object.rb +71 -0
  7. data/lib/alephant/broker/cache/client.rb +29 -17
  8. data/lib/alephant/broker/cache/null_client.rb +12 -4
  9. data/lib/alephant/broker/component.rb +3 -1
  10. data/lib/alephant/broker/component_meta.rb +2 -0
  11. data/lib/alephant/broker/error_component.rb +1 -1
  12. data/lib/alephant/broker/load_strategy.rb +1 -0
  13. data/lib/alephant/broker/load_strategy/http.rb +2 -3
  14. data/lib/alephant/broker/load_strategy/revalidate/fetcher.rb +51 -0
  15. data/lib/alephant/broker/load_strategy/revalidate/refresher.rb +75 -0
  16. data/lib/alephant/broker/load_strategy/revalidate/strategy.rb +86 -0
  17. data/lib/alephant/broker/load_strategy/s3/base.rb +2 -2
  18. data/lib/alephant/broker/response/asset.rb +1 -1
  19. data/lib/alephant/broker/response/base.rb +7 -8
  20. data/lib/alephant/broker/response/batch.rb +1 -1
  21. data/lib/alephant/broker/version.rb +1 -1
  22. data/spec/alephant/broker/cache/cached_object_spec.rb +107 -0
  23. data/spec/alephant/broker/load_strategy/http_spec.rb +5 -7
  24. data/spec/alephant/broker/load_strategy/revalidate/fetcher_spec.rb +88 -0
  25. data/spec/alephant/broker/load_strategy/revalidate/refresher_spec.rb +69 -0
  26. data/spec/alephant/broker/load_strategy/revalidate/strategy_spec.rb +185 -0
  27. data/spec/fixtures/json/batch_compiled_no_sequence.json +1 -0
  28. data/spec/integration/not_modified_response_spec.rb +4 -6
  29. data/spec/integration/rack_spec.rb +0 -3
  30. data/spec/integration/revalidate_spec.rb +174 -0
  31. data/spec/spec_helper.rb +1 -0
  32. metadata +99 -55
@@ -0,0 +1,185 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Alephant::Broker::LoadStrategy::Revalidate::Strategy do
4
+ subject { described_class.new }
5
+
6
+ let(:lookup_double) { instance_double(Alephant::Lookup::LookupHelper) }
7
+ let(:storage_double) { instance_double(Alephant::Storage) }
8
+ let(:refresher_double) { instance_double(Alephant::Broker::LoadStrategy::Revalidate::Refresher) }
9
+ let(:fetcher_double) { instance_double(Alephant::Broker::LoadStrategy::Revalidate::Fetcher) }
10
+
11
+ let(:content) do
12
+ {
13
+ content: 'Test',
14
+ content_type: 'test/content',
15
+ meta: {
16
+ :ttl => 100,
17
+ :head_ETag => '123',
18
+ :'head_Last-Modified' => Time.now.to_s
19
+ }
20
+ }
21
+ end
22
+
23
+ let(:expected_content) do
24
+ {
25
+ content: content[:content],
26
+ content_type: content[:content_type],
27
+ meta: content[:meta]
28
+ }
29
+ end
30
+
31
+ let(:cached_obj) do
32
+ Alephant::Broker::Cache::CachedObject.new(content)
33
+ end
34
+
35
+ let(:component_meta) do
36
+ Alephant::Broker::ComponentMeta.new('test', 'test_batch', {})
37
+ end
38
+
39
+ before do
40
+ allow_any_instance_of(Logger).to receive(:info)
41
+ allow_any_instance_of(Logger).to receive(:debug)
42
+ allow(Alephant::Broker).to receive(:config).and_return({})
43
+ allow(Thread).to receive(:new).and_yield
44
+ end
45
+
46
+ describe '#load' do
47
+ context 'when there is content in the cache' do
48
+ let(:cache) { subject.send(:cache) }
49
+
50
+ before do
51
+ allow(cache).to receive(:get).and_return(cached_obj)
52
+ end
53
+
54
+ context 'which is still fresh' do
55
+ before do
56
+ allow(cached_obj).to receive(:expired?).and_return(false)
57
+ end
58
+
59
+ it 'gets fetched from the cache and returned' do
60
+ expect(subject.load(component_meta)).to eq(expected_content)
61
+ end
62
+
63
+ it 'does NOT try to refresh the content' do
64
+ expect(Alephant::Broker::LoadStrategy::Revalidate::Refresher)
65
+ .to_not receive(:new)
66
+
67
+ subject.load(component_meta)
68
+ end
69
+ end
70
+
71
+ context 'which has expired' do
72
+ before do
73
+ allow(cached_obj).to receive(:expired?).and_return(true)
74
+
75
+ allow(Alephant::Broker::LoadStrategy::Revalidate::Refresher)
76
+ .to receive(:new)
77
+ .with(component_meta)
78
+ .and_return(refresher_double)
79
+
80
+ allow(refresher_double).to receive(:refresh)
81
+
82
+ allow(Alephant::Broker::LoadStrategy::Revalidate::Fetcher)
83
+ .to receive(:new)
84
+ .with(component_meta)
85
+ .and_return(fetcher_double)
86
+
87
+ allow(fetcher_double).to receive(:fetch).and_return(cached_obj)
88
+ end
89
+
90
+ it 'it gets fetched from the cache and returned to the user' do
91
+ expect(subject.load(component_meta)).to eq(expected_content)
92
+ end
93
+
94
+ context 'in the background...' do
95
+ let(:new_content) { { id: 'test', batch_id: '', meta: {} } }
96
+ let(:new_cached_obj) { Alephant::Broker::Cache::CachedObject.new(new_content) }
97
+
98
+ it 'checks the fetcher, to see if there is newer content (in S3)' do
99
+ expect(fetcher_double).to receive(:fetch).and_return(new_cached_obj)
100
+
101
+ subject.load(component_meta)
102
+ end
103
+
104
+ context 'when there IS newer, non-expired content' do
105
+ let(:cache) { subject.send(:cache) }
106
+
107
+ before do
108
+ expect(fetcher_double).to receive(:fetch).and_return(new_cached_obj)
109
+ expect(new_cached_obj).to receive(:expired?).and_return(false)
110
+ end
111
+
112
+ it 'replaces the cached content' do
113
+ expect(cache).to receive(:set).with(component_meta.component_key, new_cached_obj)
114
+
115
+ subject.load(component_meta)
116
+ end
117
+ end
118
+
119
+ context 'when there IS NOT newer content' do
120
+ before do
121
+ expect(fetcher_double).to receive(:fetch).and_return(new_cached_obj)
122
+ expect(new_cached_obj).to receive(:expired?).and_return(true)
123
+ end
124
+
125
+ it 'kicks off a refresh of the content (from the renderer)' do
126
+ expect(refresher_double).to receive(:refresh)
127
+
128
+ subject.load(component_meta)
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ context 'when there is NOT content in the cache' do
136
+ before do
137
+ allow(Alephant::Broker::LoadStrategy::Revalidate::Fetcher)
138
+ .to receive(:new)
139
+ .with(component_meta)
140
+ .and_return(fetcher_double)
141
+ end
142
+
143
+ it 'returns the data as expected' do
144
+ expect(fetcher_double).to receive(:fetch).and_return(cached_obj)
145
+ expect(subject.load(component_meta)).to eq(expected_content)
146
+ end
147
+
148
+ it 'uses the fetcher to get the data' do
149
+ expect(fetcher_double).to receive(:fetch).and_return(cached_obj)
150
+ subject.load(component_meta)
151
+ end
152
+
153
+ context 'and there is nothing returned from the fetcher' do
154
+ before do
155
+ allow(fetcher_double)
156
+ .to receive(:fetch)
157
+ .and_raise(Alephant::Broker::Errors::ContentNotFound)
158
+
159
+ expect(Alephant::Broker::LoadStrategy::Revalidate::Refresher)
160
+ .to receive(:new)
161
+ .with(component_meta)
162
+ .and_return(refresher_double)
163
+
164
+ allow(refresher_double)
165
+ .to receive(:refresh)
166
+ end
167
+
168
+ it 'kicks off a refresh of the content' do
169
+ expect(refresher_double).to receive(:refresh)
170
+ subject.load(component_meta)
171
+ end
172
+
173
+ it 'returns a response that will invoke a 202 (HTTP) response' do
174
+ expected_response = {
175
+ content: '',
176
+ content_type: 'text/html',
177
+ meta: { status: 202 }
178
+ }
179
+
180
+ expect(subject.load(component_meta)).to eq(expected_response)
181
+ end
182
+ end
183
+ end
184
+ end
185
+ end
@@ -0,0 +1 @@
1
+ {"batch_id":"baz","components":[{"component":"ni_council_results_table","options":{"foo":"bar"},"status":200,"content_type":"test/content","body":"Test"},{"component":"ni_council_results_table","options":{},"status":200,"content_type":"test/content","body":"Test"}]}
@@ -50,8 +50,6 @@ describe Alephant::Broker::Application do
50
50
 
51
51
  let(:s3_double) { instance_double("Alephant::Storage", :get => content) }
52
52
 
53
- let(:not_modified_status_code) { Alephant::Broker::Response::Base::NOT_MODIFIED_STATUS_CODE }
54
-
55
53
  before do
56
54
  allow_any_instance_of(Logger).to receive(:info)
57
55
  allow_any_instance_of(Logger).to receive(:debug)
@@ -69,8 +67,8 @@ describe Alephant::Broker::Application do
69
67
  )
70
68
  end
71
69
 
72
- specify { expect(last_response.status).to eql not_modified_status_code }
73
- specify { expect(last_response.body).to eql "" }
70
+ specify { expect(last_response.status).to eql(304) }
71
+ specify { expect(last_response.body).to eql("") }
74
72
  specify { expect(last_response.headers).to_not include("Cache-Control") }
75
73
  specify { expect(last_response.headers).to_not include("Pragma") }
76
74
  specify { expect(last_response.headers).to_not include("Expires") }
@@ -199,8 +197,8 @@ describe Alephant::Broker::Application do
199
197
  )
200
198
  end
201
199
 
202
- specify { expect(last_response.status).to eql not_modified_status_code }
203
- specify { expect(last_response.body).to eq "" }
200
+ specify { expect(last_response.status).to eql(304) }
201
+ specify { expect(last_response.body).to eq("") }
204
202
 
205
203
  describe "response should have headers" do
206
204
  it "should not have a Content-Type header" do
@@ -1,5 +1,4 @@
1
1
  require_relative "spec_helper"
2
- require "alephant/broker"
3
2
 
4
3
  describe Alephant::Broker::Application do
5
4
  include Rack::Test::Methods
@@ -49,8 +48,6 @@ describe Alephant::Broker::Application do
49
48
 
50
49
  let(:s3_double) { instance_double("Alephant::Storage", :get => content) }
51
50
 
52
- let(:not_modified_status_code) { Alephant::Broker::Response::Base::NOT_MODIFIED_STATUS_CODE }
53
-
54
51
  before do
55
52
  allow_any_instance_of(Logger).to receive(:info)
56
53
  allow_any_instance_of(Logger).to receive(:debug)
@@ -0,0 +1,174 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe Alephant::Broker::Application do
4
+ include Rack::Test::Methods
5
+
6
+ let(:config) do
7
+ {
8
+ aws_account_id: '12345',
9
+ lookup_table_name: 'test_table',
10
+ s3_bucket_id: 'test_bucket',
11
+ s3_object_path: 'bucket_path',
12
+ sqs_queue_name: 'test_queue'
13
+ }
14
+ end
15
+
16
+ let(:app) do
17
+ described_class.new(
18
+ Alephant::Broker::LoadStrategy::Revalidate::Strategy.new,
19
+ config
20
+ )
21
+ end
22
+
23
+ let(:content) do
24
+ {
25
+ content: 'Test',
26
+ content_type: 'test/content',
27
+ meta: {
28
+ :ttl => '35',
29
+ :head_ETag => '123',
30
+ :'head_Last-Modified' => 'Mon, 11 Apr 2016 10:39:57 GMT'
31
+ }
32
+ }
33
+ end
34
+
35
+ let(:lookup_location_double) { instance_double(Alephant::Lookup::LookupLocation, location: 'test/location') }
36
+ let(:lookup_helper_double) { instance_double(Alephant::Lookup::LookupHelper, read: lookup_location_double) }
37
+ let(:storage_double) { instance_double(Alephant::Storage, get: content) }
38
+ let(:sqs_double) { instance_double(AWS::SQS, queues: sqs_queues_double) }
39
+ let(:sqs_queue_double) { instance_double(AWS::SQS::Queue, send_message: nil) }
40
+ let(:sqs_queues_double) { instance_double(AWS::SQS::QueueCollection, :url_for => 'example.com', :[] => sqs_queue_double) }
41
+
42
+ before do
43
+ allow_any_instance_of(Logger).to receive(:info)
44
+ allow_any_instance_of(Logger).to receive(:debug)
45
+ allow(Thread).to receive(:new).and_yield
46
+ allow(Alephant::Lookup).to receive(:create).and_return(lookup_helper_double)
47
+ allow(Alephant::Storage).to receive(:new).and_return(storage_double)
48
+ allow(AWS::SQS).to receive(:new).and_return(sqs_double)
49
+ end
50
+
51
+ describe 'GET `/status`' do
52
+ before { get('/status') }
53
+ specify { expect(last_response.status).to eql(200) }
54
+ specify { expect(last_response.body).to eql('ok') }
55
+ end
56
+
57
+ describe 'GET an undefined endpoint' do
58
+ before { get('/wotever') }
59
+ specify { expect(last_response.status).to eql(404) }
60
+ specify { expect(last_response.body).to eq('Not found') }
61
+ specify { expect(last_response.headers).to include('Cache-Control') }
62
+ specify { expect(last_response.headers).to include('Pragma') }
63
+ specify { expect(last_response.headers).to include('Expires') }
64
+ end
65
+
66
+ describe 'GET `/component/....`' do
67
+ context 'when the content IS available from S3/storage' do
68
+ before { get('/component/test_component') }
69
+
70
+ specify { expect(last_response.status).to eql(200) }
71
+ specify { expect(last_response.body).to eql('Test') }
72
+ specify { expect(last_response.headers).to_not include('Cache-Control') }
73
+ specify { expect(last_response.headers).to_not include('Pragma') }
74
+ specify { expect(last_response.headers).to_not include('Expires') }
75
+ specify { expect(last_response.headers['ETag']).to eq('123') }
76
+ specify { expect(last_response.headers['Last-Modified']).to eq('Mon, 11 Apr 2016 10:39:57 GMT') }
77
+ specify { expect(last_response.headers['Content-Type']).to eq('test/content') }
78
+ specify { expect(last_response.headers['Content-Length']).to eq('4') }
79
+ end
80
+
81
+ context 'when the content IS NOT available from S3/storage' do
82
+ before do
83
+ allow(storage_double)
84
+ .to receive(:get)
85
+ .and_raise(AWS::S3::Errors::NoSuchKey.new(nil, nil))
86
+
87
+ get('/component/test_component')
88
+ end
89
+
90
+ specify { expect(last_response.status).to eql(202) }
91
+ specify { expect(last_response.body).to eql('Accepted') }
92
+ end
93
+ end
94
+
95
+ describe '`/components`' do
96
+ let(:fixture_path) { "#{File.dirname(__FILE__)}/../fixtures/json" }
97
+ let(:batch_json) { IO.read("#{fixture_path}/batch.json").strip }
98
+ let(:batch_compiled_json) { IO.read("#{fixture_path}/batch_compiled_no_sequence.json").strip }
99
+
100
+ before do
101
+ allow(storage_double)
102
+ .to receive(:get)
103
+ .and_return(
104
+ content,
105
+ {
106
+ content: 'Test',
107
+ content_type: 'test/content',
108
+ meta: {
109
+ :head_ETag => '"abc"',
110
+ :'head_Last-Modified' => 'Mon, 11 Apr 2016 09:39:57 GMT'
111
+ }
112
+ }
113
+ )
114
+ end
115
+
116
+ describe 'POST' do
117
+ let(:path) { '/components/batch' }
118
+ let(:content_type) { 'application/json' }
119
+
120
+ context 'when the content is available from S3/Storage' do
121
+ before { post(path, batch_json, 'CONTENT_TYPE' => content_type) }
122
+
123
+ specify { expect(last_response.status).to eql(200) }
124
+ specify { expect(last_response.body).to eq(batch_compiled_json) }
125
+ end
126
+
127
+ context 'when the content IS NOT available from S3/storage' do
128
+ before do
129
+ allow(storage_double)
130
+ .to receive(:get)
131
+ .and_raise(AWS::S3::Errors::NoSuchKey.new(nil, nil))
132
+
133
+ post(path, batch_json, 'CONTENT_TYPE' => content_type)
134
+ end
135
+
136
+ specify { expect(last_response.status).to eql(200) }
137
+
138
+ specify do
139
+ statuses = JSON.parse(last_response.body)['components'].map { |c| c['status'] }
140
+ expect(statuses).to eq([202, 202])
141
+ end
142
+ end
143
+ end
144
+
145
+ describe 'GET' do
146
+ let(:path) { '/components/batch?batch_id=baz&components[ni_council_results_table][component]=ni_council_results_table&components[ni_council_results_table][options][foo]=bar&components[ni_council_results_table_no_options][component]=ni_council_results_table' }
147
+ let(:content_type) { 'application/json' }
148
+
149
+ context 'when the content is available from S3/Storage' do
150
+ before { get(path, {}, 'CONTENT_TYPE' => content_type) }
151
+
152
+ specify { expect(last_response.status).to eql(200) }
153
+ specify { expect(last_response.body).to eq(batch_compiled_json) }
154
+ end
155
+
156
+ context 'when the content IS NOT available from S3/storage' do
157
+ before do
158
+ allow(storage_double)
159
+ .to receive(:get)
160
+ .and_raise(AWS::S3::Errors::NoSuchKey.new(nil, nil))
161
+
162
+ get(path, {}, 'CONTENT_TYPE' => content_type)
163
+ end
164
+
165
+ specify { expect(last_response.status).to eql(200) }
166
+
167
+ specify do
168
+ statuses = JSON.parse(last_response.body)['components'].map { |c| c['status'] }
169
+ expect(statuses).to eq([202, 202])
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
@@ -9,6 +9,7 @@ end
9
9
  require "pry"
10
10
  require "json"
11
11
  require "rack/test"
12
+ require "timecop"
12
13
 
13
14
  require "alephant/broker"
14
15
 
metadata CHANGED
@@ -1,295 +1,323 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alephant-broker
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.14.0
4
+ version: 3.15.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-06-06 00:00:00.000000000 Z
11
+ date: 2016-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ version_requirements: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
14
20
  requirement: !ruby/object:Gem::Requirement
15
21
  requirements:
16
22
  - - '>='
17
23
  - !ruby/object:Gem::Version
18
24
  version: '0'
19
- name: rspec
20
25
  prerelease: false
21
26
  type: :development
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec-nc
22
29
  version_requirements: !ruby/object:Gem::Requirement
23
30
  requirements:
24
31
  - - '>='
25
32
  - !ruby/object:Gem::Version
26
33
  version: '0'
27
- - !ruby/object:Gem::Dependency
28
34
  requirement: !ruby/object:Gem::Requirement
29
35
  requirements:
30
36
  - - '>='
31
37
  - !ruby/object:Gem::Version
32
38
  version: '0'
33
- name: rspec-nc
34
39
  prerelease: false
35
40
  type: :development
41
+ - !ruby/object:Gem::Dependency
42
+ name: guard
36
43
  version_requirements: !ruby/object:Gem::Requirement
37
44
  requirements:
38
45
  - - '>='
39
46
  - !ruby/object:Gem::Version
40
47
  version: '0'
41
- - !ruby/object:Gem::Dependency
42
48
  requirement: !ruby/object:Gem::Requirement
43
49
  requirements:
44
50
  - - '>='
45
51
  - !ruby/object:Gem::Version
46
52
  version: '0'
47
- name: guard
48
53
  prerelease: false
49
54
  type: :development
55
+ - !ruby/object:Gem::Dependency
56
+ name: guard-rspec
50
57
  version_requirements: !ruby/object:Gem::Requirement
51
58
  requirements:
52
59
  - - '>='
53
60
  - !ruby/object:Gem::Version
54
61
  version: '0'
55
- - !ruby/object:Gem::Dependency
56
62
  requirement: !ruby/object:Gem::Requirement
57
63
  requirements:
58
64
  - - '>='
59
65
  - !ruby/object:Gem::Version
60
66
  version: '0'
61
- name: guard-rspec
62
67
  prerelease: false
63
68
  type: :development
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
64
71
  version_requirements: !ruby/object:Gem::Requirement
65
72
  requirements:
66
73
  - - '>='
67
74
  - !ruby/object:Gem::Version
68
75
  version: '0'
69
- - !ruby/object:Gem::Dependency
70
76
  requirement: !ruby/object:Gem::Requirement
71
77
  requirements:
72
78
  - - '>='
73
79
  - !ruby/object:Gem::Version
74
80
  version: '0'
75
- name: pry
76
81
  prerelease: false
77
82
  type: :development
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry-remote
78
85
  version_requirements: !ruby/object:Gem::Requirement
79
86
  requirements:
80
87
  - - '>='
81
88
  - !ruby/object:Gem::Version
82
89
  version: '0'
83
- - !ruby/object:Gem::Dependency
84
90
  requirement: !ruby/object:Gem::Requirement
85
91
  requirements:
86
92
  - - '>='
87
93
  - !ruby/object:Gem::Version
88
94
  version: '0'
89
- name: pry-remote
90
95
  prerelease: false
91
96
  type: :development
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry-nav
92
99
  version_requirements: !ruby/object:Gem::Requirement
93
100
  requirements:
94
101
  - - '>='
95
102
  - !ruby/object:Gem::Version
96
103
  version: '0'
97
- - !ruby/object:Gem::Dependency
98
104
  requirement: !ruby/object:Gem::Requirement
99
105
  requirements:
100
106
  - - '>='
101
107
  - !ruby/object:Gem::Version
102
108
  version: '0'
103
- name: pry-nav
104
109
  prerelease: false
105
110
  type: :development
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake-rspec
106
113
  version_requirements: !ruby/object:Gem::Requirement
107
114
  requirements:
108
115
  - - '>='
109
116
  - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
117
+ version: 0.0.2
112
118
  requirement: !ruby/object:Gem::Requirement
113
119
  requirements:
114
120
  - - '>='
115
121
  - !ruby/object:Gem::Version
116
122
  version: 0.0.2
117
- name: rake-rspec
118
123
  prerelease: false
119
124
  type: :development
125
+ - !ruby/object:Gem::Dependency
126
+ name: bundler
120
127
  version_requirements: !ruby/object:Gem::Requirement
121
128
  requirements:
122
- - - '>='
129
+ - - ~>
123
130
  - !ruby/object:Gem::Version
124
- version: 0.0.2
125
- - !ruby/object:Gem::Dependency
131
+ version: '1.5'
126
132
  requirement: !ruby/object:Gem::Requirement
127
133
  requirements:
128
134
  - - ~>
129
135
  - !ruby/object:Gem::Version
130
136
  version: '1.5'
131
- name: bundler
132
137
  prerelease: false
133
138
  type: :development
139
+ - !ruby/object:Gem::Dependency
140
+ name: rake
134
141
  version_requirements: !ruby/object:Gem::Requirement
135
142
  requirements:
136
- - - ~>
143
+ - - '>='
137
144
  - !ruby/object:Gem::Version
138
- version: '1.5'
139
- - !ruby/object:Gem::Dependency
145
+ version: '0'
140
146
  requirement: !ruby/object:Gem::Requirement
141
147
  requirements:
142
148
  - - '>='
143
149
  - !ruby/object:Gem::Version
144
150
  version: '0'
145
- name: rake
146
151
  prerelease: false
147
152
  type: :development
153
+ - !ruby/object:Gem::Dependency
154
+ name: rack
155
+ version_requirements: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - <
158
+ - !ruby/object:Gem::Version
159
+ version: 2.0.0
160
+ requirement: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - <
163
+ - !ruby/object:Gem::Version
164
+ version: 2.0.0
165
+ prerelease: false
166
+ type: :development
167
+ - !ruby/object:Gem::Dependency
168
+ name: rack-test
148
169
  version_requirements: !ruby/object:Gem::Requirement
149
170
  requirements:
150
171
  - - '>='
151
172
  - !ruby/object:Gem::Version
152
173
  version: '0'
153
- - !ruby/object:Gem::Dependency
154
174
  requirement: !ruby/object:Gem::Requirement
155
175
  requirements:
156
176
  - - '>='
157
177
  - !ruby/object:Gem::Version
158
178
  version: '0'
159
- name: rack-test
160
179
  prerelease: false
161
180
  type: :development
181
+ - !ruby/object:Gem::Dependency
182
+ name: simplecov
162
183
  version_requirements: !ruby/object:Gem::Requirement
163
184
  requirements:
164
185
  - - '>='
165
186
  - !ruby/object:Gem::Version
166
187
  version: '0'
167
- - !ruby/object:Gem::Dependency
168
188
  requirement: !ruby/object:Gem::Requirement
169
189
  requirements:
170
190
  - - '>='
171
191
  - !ruby/object:Gem::Version
172
192
  version: '0'
173
- name: simplecov
174
193
  prerelease: false
175
194
  type: :development
195
+ - !ruby/object:Gem::Dependency
196
+ name: timecop
176
197
  version_requirements: !ruby/object:Gem::Requirement
177
198
  requirements:
178
199
  - - '>='
179
200
  - !ruby/object:Gem::Version
180
201
  version: '0'
181
- - !ruby/object:Gem::Dependency
182
202
  requirement: !ruby/object:Gem::Requirement
183
203
  requirements:
184
204
  - - '>='
185
205
  - !ruby/object:Gem::Version
186
206
  version: '0'
187
- name: alephant-lookup
188
207
  prerelease: false
189
- type: :runtime
208
+ type: :development
209
+ - !ruby/object:Gem::Dependency
210
+ name: alephant-lookup
190
211
  version_requirements: !ruby/object:Gem::Requirement
191
212
  requirements:
192
213
  - - '>='
193
214
  - !ruby/object:Gem::Version
194
- version: '0'
195
- - !ruby/object:Gem::Dependency
215
+ version: 2.0.2
196
216
  requirement: !ruby/object:Gem::Requirement
197
217
  requirements:
198
218
  - - '>='
199
219
  - !ruby/object:Gem::Version
200
- version: 1.1.1
201
- name: alephant-storage
220
+ version: 2.0.2
202
221
  prerelease: false
203
222
  type: :runtime
223
+ - !ruby/object:Gem::Dependency
224
+ name: alephant-storage
204
225
  version_requirements: !ruby/object:Gem::Requirement
205
226
  requirements:
206
227
  - - '>='
207
228
  - !ruby/object:Gem::Version
208
229
  version: 1.1.1
209
- - !ruby/object:Gem::Dependency
210
230
  requirement: !ruby/object:Gem::Requirement
211
231
  requirements:
212
- - - '='
232
+ - - '>='
213
233
  - !ruby/object:Gem::Version
214
- version: 1.2.0
215
- name: alephant-logger
234
+ version: 1.1.1
216
235
  prerelease: false
217
236
  type: :runtime
237
+ - !ruby/object:Gem::Dependency
238
+ name: alephant-logger
218
239
  version_requirements: !ruby/object:Gem::Requirement
219
240
  requirements:
220
241
  - - '='
221
242
  - !ruby/object:Gem::Version
222
243
  version: 1.2.0
223
- - !ruby/object:Gem::Dependency
224
244
  requirement: !ruby/object:Gem::Requirement
225
245
  requirements:
226
- - - '>='
246
+ - - '='
227
247
  - !ruby/object:Gem::Version
228
- version: '0'
229
- name: alephant-sequencer
248
+ version: 1.2.0
230
249
  prerelease: false
231
250
  type: :runtime
251
+ - !ruby/object:Gem::Dependency
252
+ name: alephant-sequencer
232
253
  version_requirements: !ruby/object:Gem::Requirement
233
254
  requirements:
234
255
  - - '>='
235
256
  - !ruby/object:Gem::Version
236
257
  version: '0'
237
- - !ruby/object:Gem::Dependency
238
258
  requirement: !ruby/object:Gem::Requirement
239
259
  requirements:
240
260
  - - '>='
241
261
  - !ruby/object:Gem::Version
242
262
  version: '0'
243
- name: dalli-elasticache
244
263
  prerelease: false
245
264
  type: :runtime
265
+ - !ruby/object:Gem::Dependency
266
+ name: dalli-elasticache
246
267
  version_requirements: !ruby/object:Gem::Requirement
247
268
  requirements:
248
269
  - - '>='
249
270
  - !ruby/object:Gem::Version
250
271
  version: '0'
251
- - !ruby/object:Gem::Dependency
252
272
  requirement: !ruby/object:Gem::Requirement
253
273
  requirements:
254
274
  - - '>='
255
275
  - !ruby/object:Gem::Version
256
276
  version: '0'
257
- name: faraday
258
277
  prerelease: false
259
278
  type: :runtime
279
+ - !ruby/object:Gem::Dependency
280
+ name: faraday
260
281
  version_requirements: !ruby/object:Gem::Requirement
261
282
  requirements:
262
283
  - - '>='
263
284
  - !ruby/object:Gem::Version
264
285
  version: '0'
265
- - !ruby/object:Gem::Dependency
266
286
  requirement: !ruby/object:Gem::Requirement
267
287
  requirements:
268
288
  - - '>='
269
289
  - !ruby/object:Gem::Version
270
290
  version: '0'
271
- name: crimp
272
291
  prerelease: false
273
292
  type: :runtime
293
+ - !ruby/object:Gem::Dependency
294
+ name: crimp
274
295
  version_requirements: !ruby/object:Gem::Requirement
275
296
  requirements:
276
297
  - - '>='
277
298
  - !ruby/object:Gem::Version
278
299
  version: '0'
279
- - !ruby/object:Gem::Dependency
280
300
  requirement: !ruby/object:Gem::Requirement
281
301
  requirements:
282
- - - ~>
302
+ - - '>='
283
303
  - !ruby/object:Gem::Version
284
- version: 3.0.0
285
- name: listen
304
+ version: '0'
286
305
  prerelease: false
287
306
  type: :runtime
307
+ - !ruby/object:Gem::Dependency
308
+ name: listen
288
309
  version_requirements: !ruby/object:Gem::Requirement
289
310
  requirements:
290
311
  - - ~>
291
312
  - !ruby/object:Gem::Version
292
313
  version: 3.0.0
314
+ requirement: !ruby/object:Gem::Requirement
315
+ requirements:
316
+ - - ~>
317
+ - !ruby/object:Gem::Version
318
+ version: 3.0.0
319
+ prerelease: false
320
+ type: :runtime
293
321
  description: Brokers requests for alephant components
294
322
  email:
295
323
  - FutureMediaNewsRubyGems@bbc.co.uk
@@ -309,6 +337,7 @@ files:
309
337
  - lib/alephant/broker.rb
310
338
  - lib/alephant/broker/application.rb
311
339
  - lib/alephant/broker/cache.rb
340
+ - lib/alephant/broker/cache/cached_object.rb
312
341
  - lib/alephant/broker/cache/client.rb
313
342
  - lib/alephant/broker/cache/null_client.rb
314
343
  - lib/alephant/broker/component.rb
@@ -322,6 +351,9 @@ files:
322
351
  - lib/alephant/broker/errors/invalid_cache_key.rb
323
352
  - lib/alephant/broker/load_strategy.rb
324
353
  - lib/alephant/broker/load_strategy/http.rb
354
+ - lib/alephant/broker/load_strategy/revalidate/fetcher.rb
355
+ - lib/alephant/broker/load_strategy/revalidate/refresher.rb
356
+ - lib/alephant/broker/load_strategy/revalidate/strategy.rb
325
357
  - lib/alephant/broker/load_strategy/s3/archived.rb
326
358
  - lib/alephant/broker/load_strategy/s3/base.rb
327
359
  - lib/alephant/broker/load_strategy/s3/sequenced.rb
@@ -336,13 +368,19 @@ files:
336
368
  - lib/alephant/broker/response/batch.rb
337
369
  - lib/alephant/broker/response/factory.rb
338
370
  - lib/alephant/broker/version.rb
371
+ - spec/alephant/broker/cache/cached_object_spec.rb
339
372
  - spec/alephant/broker/component_meta_spec.rb
340
373
  - spec/alephant/broker/load_strategy/http_spec.rb
374
+ - spec/alephant/broker/load_strategy/revalidate/fetcher_spec.rb
375
+ - spec/alephant/broker/load_strategy/revalidate/refresher_spec.rb
376
+ - spec/alephant/broker/load_strategy/revalidate/strategy_spec.rb
341
377
  - spec/alephant/broker/load_strategy/s3/archived_spec.rb
342
378
  - spec/fixtures/json/batch.json
343
379
  - spec/fixtures/json/batch_compiled.json
380
+ - spec/fixtures/json/batch_compiled_no_sequence.json
344
381
  - spec/integration/not_modified_response_spec.rb
345
382
  - spec/integration/rack_spec.rb
383
+ - spec/integration/revalidate_spec.rb
346
384
  - spec/integration/spec_helper.rb
347
385
  - spec/spec_helper.rb
348
386
  homepage: https://github.com/BBC-News/alephant-broker
@@ -370,12 +408,18 @@ signing_key:
370
408
  specification_version: 4
371
409
  summary: Brokers requests for alephant components
372
410
  test_files:
411
+ - spec/alephant/broker/cache/cached_object_spec.rb
373
412
  - spec/alephant/broker/component_meta_spec.rb
374
413
  - spec/alephant/broker/load_strategy/http_spec.rb
414
+ - spec/alephant/broker/load_strategy/revalidate/fetcher_spec.rb
415
+ - spec/alephant/broker/load_strategy/revalidate/refresher_spec.rb
416
+ - spec/alephant/broker/load_strategy/revalidate/strategy_spec.rb
375
417
  - spec/alephant/broker/load_strategy/s3/archived_spec.rb
376
418
  - spec/fixtures/json/batch.json
377
419
  - spec/fixtures/json/batch_compiled.json
420
+ - spec/fixtures/json/batch_compiled_no_sequence.json
378
421
  - spec/integration/not_modified_response_spec.rb
379
422
  - spec/integration/rack_spec.rb
423
+ - spec/integration/revalidate_spec.rb
380
424
  - spec/integration/spec_helper.rb
381
425
  - spec/spec_helper.rb