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.
- checksums.yaml +4 -4
- data/.travis.yml +22 -9
- data/README.md +35 -6
- data/alephant-broker.gemspec +3 -2
- data/lib/alephant/broker/cache.rb +1 -0
- data/lib/alephant/broker/cache/cached_object.rb +71 -0
- data/lib/alephant/broker/cache/client.rb +29 -17
- data/lib/alephant/broker/cache/null_client.rb +12 -4
- data/lib/alephant/broker/component.rb +3 -1
- data/lib/alephant/broker/component_meta.rb +2 -0
- data/lib/alephant/broker/error_component.rb +1 -1
- data/lib/alephant/broker/load_strategy.rb +1 -0
- data/lib/alephant/broker/load_strategy/http.rb +2 -3
- data/lib/alephant/broker/load_strategy/revalidate/fetcher.rb +51 -0
- data/lib/alephant/broker/load_strategy/revalidate/refresher.rb +75 -0
- data/lib/alephant/broker/load_strategy/revalidate/strategy.rb +86 -0
- data/lib/alephant/broker/load_strategy/s3/base.rb +2 -2
- data/lib/alephant/broker/response/asset.rb +1 -1
- data/lib/alephant/broker/response/base.rb +7 -8
- data/lib/alephant/broker/response/batch.rb +1 -1
- data/lib/alephant/broker/version.rb +1 -1
- data/spec/alephant/broker/cache/cached_object_spec.rb +107 -0
- data/spec/alephant/broker/load_strategy/http_spec.rb +5 -7
- data/spec/alephant/broker/load_strategy/revalidate/fetcher_spec.rb +88 -0
- data/spec/alephant/broker/load_strategy/revalidate/refresher_spec.rb +69 -0
- data/spec/alephant/broker/load_strategy/revalidate/strategy_spec.rb +185 -0
- data/spec/fixtures/json/batch_compiled_no_sequence.json +1 -0
- data/spec/integration/not_modified_response_spec.rb +4 -6
- data/spec/integration/rack_spec.rb +0 -3
- data/spec/integration/revalidate_spec.rb +174 -0
- data/spec/spec_helper.rb +1 -0
- 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
|
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
|
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
|
data/spec/spec_helper.rb
CHANGED
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.
|
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-
|
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:
|
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:
|
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: '
|
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: :
|
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:
|
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:
|
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.
|
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:
|
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:
|
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
|