lhs 10.1.1 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Gemfile.activesupport4 +4 -0
- data/Gemfile.activesupport5 +4 -0
- data/README.md +34 -5
- data/Rakefile +1 -2
- data/cider-ci.yml +3 -1
- data/cider-ci/bin/bundle +11 -1
- data/cider-ci/jobs/rspec-activesupport-4.yml +26 -0
- data/cider-ci/jobs/rspec-activesupport-5.yml +26 -0
- data/cider-ci/jobs/{rspec.yml → rspec-activesupport-latest.yml} +3 -3
- data/cider-ci/task_components/rspec.yml +1 -2
- data/lhs.gemspec +2 -3
- data/lib/lhs.rb +9 -1
- data/lib/lhs/concerns/lhs/configuration.rb +18 -0
- data/lib/lhs/concerns/record/request.rb +14 -0
- data/lib/lhs/concerns/record/request_cycle_cache/interceptor.rb +38 -0
- data/lib/lhs/concerns/record/request_cycle_cache/request_cycle_thread_registry.rb +13 -0
- data/lib/lhs/config.rb +11 -0
- data/lib/lhs/railtie.rb +20 -0
- data/lib/lhs/record.rb +1 -0
- data/lib/lhs/version.rb +1 -1
- data/spec/autoloading_spec.rb +4 -4
- data/spec/dummy/app/controllers/request_cycle_cache_controller.rb +25 -0
- data/spec/dummy/app/models/user.rb +2 -2
- data/spec/dummy/config/environments/test.rb +0 -4
- data/spec/dummy/config/routes.rb +4 -53
- data/spec/record/includes_warning_spec.rb +1 -1
- data/spec/record/request_spec.rb +3 -2
- data/spec/request_cycle_cache/main_spec.rb +90 -0
- data/spec/support/request_cycle_cache.rb +7 -0
- metadata +23 -24
- data/spec/dummy/config/initializers/lhc.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47b77a705ee21920e7c48515fdf200b60bb2be61
|
4
|
+
data.tar.gz: d85c7e29b814b6ddda3c0729c1adfb405cc6e873
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6351281d1b7f3d3c5cc08fe91ac35f6a747d6ffa543a41b9a6737e2634bc714fe1a340453ab887030af652063afdd3305c4da811ef1bafaab8acb89ba0cd12bf
|
7
|
+
data.tar.gz: 8aef3ee080ad5d7b6d0937138434ab2758b3941dfdfcc4fddbc38beb5a1dc16507b2929a4069dbc8ee5fbb09c4a59757a1adbfc3f1bab0cb23f8644fa43f0cf1
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -3,6 +3,21 @@ LHS
|
|
3
3
|
|
4
4
|
LHS uses [LHC](//github.com/local-ch/LHC) for http requests.
|
5
5
|
|
6
|
+
## Quickstart
|
7
|
+
|
8
|
+
```
|
9
|
+
gem 'lhs'
|
10
|
+
```
|
11
|
+
|
12
|
+
LHS comes with Request Cycle Cache – enabled by default. It requires [LHC Caching Interceptor](https://github.com/local-ch/lhc/blob/master/docs/interceptors/caching.md) to be enabled:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
# intializers/lhc.rb
|
16
|
+
LHC.configure do |config|
|
17
|
+
config.interceptors = [LHC::Caching]
|
18
|
+
end
|
19
|
+
```
|
20
|
+
|
6
21
|
## Very Short Introduction
|
7
22
|
|
8
23
|
Access data that is provided by an http json service with ease using a LHS::Record.
|
@@ -27,15 +42,13 @@ Please store all defined LHS::Records in `app/models` as they are not autoloaded
|
|
27
42
|
|
28
43
|
You setup a LHS::Record by configuring one or multiple endpoints. You can also add request options for an endpoint (see following example).
|
29
44
|
|
30
|
-
The following example uses the `LHC::Caching` interceptor from [lhc-core-interceptors](https://github.com/local-ch/lhc-core-interceptors#cache-interceptor).
|
31
|
-
|
32
45
|
```ruby
|
33
46
|
class Record < LHS::Record
|
34
47
|
|
35
48
|
endpoint ':service/v2/association/:association_id/records'
|
36
49
|
endpoint ':service/v2/association/:association_id/records/:id'
|
37
|
-
endpoint ':service/v2/records',
|
38
|
-
endpoint ':service/v2/records/:id',
|
50
|
+
endpoint ':service/v2/records', auth: { basic: 'PASSWORD' }
|
51
|
+
endpoint ':service/v2/records/:id', auth: { basic: 'PASSWORD' }
|
39
52
|
|
40
53
|
end
|
41
54
|
```
|
@@ -179,7 +192,7 @@ record = Record.where(color: 'blue')
|
|
179
192
|
|
180
193
|
If no record is found an error is raised.
|
181
194
|
|
182
|
-
`find` can also be used to find a single
|
195
|
+
`find` can also be used to find a single unique record with parameters:
|
183
196
|
|
184
197
|
```ruby
|
185
198
|
Record.find(association_id: 123, id: 456)
|
@@ -262,6 +275,22 @@ You can apply options to the request chain. Those options will be forwarded to t
|
|
262
275
|
authenticated_record.update(name: 'Steve')
|
263
276
|
```
|
264
277
|
|
278
|
+
## Request Cycle Cache
|
279
|
+
|
280
|
+
By default, LHS does not perform the same http request during one request cycle multiple times.
|
281
|
+
|
282
|
+
It uses the [LHC Caching Interceptor](https://github.com/local-ch/lhc/blob/master/docs/interceptors/caching.md) as caching mechanism base and sets a unique request id for every request cycle with Railties to ensure data is just cached within one request cycle and not shared with other requests.
|
283
|
+
|
284
|
+
Only GET requests are considered for caching by using LHC Caching Interceptor's `cache_methods` option internaly and considers request headers when caching requests, so requests with different headers are not served from cache.
|
285
|
+
|
286
|
+
The LHS Request Cycle Cache is opt-out, so it's enabled by default and will require you to enable the [LHC Caching Interceptor](https://github.com/local-ch/lhc/blob/master/docs/interceptors/caching.md) in your project.
|
287
|
+
|
288
|
+
If you want to disable the LHS Request Cycle Cache, simply disable it within configuration:
|
289
|
+
|
290
|
+
```ruby
|
291
|
+
LHS.config.request_cycle_cache_enabled = false
|
292
|
+
```
|
293
|
+
|
265
294
|
## Batch processing
|
266
295
|
|
267
296
|
**Be careful using methods for batch processing. They could result in a lot of HTTP requests!**
|
data/Rakefile
CHANGED
data/cider-ci.yml
CHANGED
data/cider-ci/bin/bundle
CHANGED
@@ -15,13 +15,23 @@ DIGEST=$(git ls-tree HEAD --\
|
|
15
15
|
cider-ci.yml cider-ci Gemfile.lock \
|
16
16
|
| openssl dgst -sha1 | cut -d ' ' -f 2)
|
17
17
|
|
18
|
+
if [ ! -z ${ACTIVESUPPORT:-} ]; then
|
19
|
+
DIGEST=$(echo "$DIGEST $ACTIVESUPPORT")
|
20
|
+
fi
|
21
|
+
|
18
22
|
DIGEST=$(echo "$DIGEST $PATH" \
|
19
23
|
| openssl dgst -sha1 | cut -d ' ' -f 2)
|
20
24
|
|
21
25
|
CACHE_SIGNATURE_FILE="/tmp/bundle_cache_signature_${DIGEST}"
|
22
26
|
|
23
27
|
if [ ! -f $CACHE_SIGNATURE_FILE ] ; then
|
24
|
-
|
28
|
+
if [ ! -z ${ACTIVESUPPORT:-} ]; then
|
29
|
+
echo "BUNDLE_GEMFILE=Gemfile.activesupport$ACTIVESUPPORT bundle install"
|
30
|
+
BUNDLE_GEMFILE=Gemfile.activesupport$ACTIVESUPPORT bundle install
|
31
|
+
else
|
32
|
+
echo "bundle install"
|
33
|
+
bundle install
|
34
|
+
fi
|
25
35
|
touch $CACHE_SIGNATURE_FILE
|
26
36
|
fi
|
27
37
|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
rspec-active-support-v4:
|
2
|
+
name: 'rspec with ActiveSupport v4'
|
3
|
+
|
4
|
+
run_when:
|
5
|
+
'some HEAD has been updated':
|
6
|
+
type: branch
|
7
|
+
include_match: ^.*$
|
8
|
+
|
9
|
+
context:
|
10
|
+
|
11
|
+
script_defaults:
|
12
|
+
template_environment_variables: true
|
13
|
+
|
14
|
+
task_defaults:
|
15
|
+
environment_variables:
|
16
|
+
ACTIVESUPPORT: '4'
|
17
|
+
max_trials: 2
|
18
|
+
dispatch_storm_delay_duration: 1 Seconds
|
19
|
+
include:
|
20
|
+
- cider-ci/task_components/ruby.yml
|
21
|
+
- cider-ci/task_components/bundle.yml
|
22
|
+
- cider-ci/task_components/rspec.yml
|
23
|
+
|
24
|
+
tasks:
|
25
|
+
all-rspec:
|
26
|
+
name: All rspec tests, using ActiveSupport v4
|
@@ -0,0 +1,26 @@
|
|
1
|
+
rspec-active-support-v5:
|
2
|
+
name: 'rspec with ActiveSupport v5'
|
3
|
+
|
4
|
+
run_when:
|
5
|
+
'some HEAD has been updated':
|
6
|
+
type: branch
|
7
|
+
include_match: ^.*$
|
8
|
+
|
9
|
+
context:
|
10
|
+
|
11
|
+
script_defaults:
|
12
|
+
template_environment_variables: true
|
13
|
+
|
14
|
+
task_defaults:
|
15
|
+
environment_variables:
|
16
|
+
ACTIVESUPPORT: '5'
|
17
|
+
max_trials: 2
|
18
|
+
dispatch_storm_delay_duration: 1 Seconds
|
19
|
+
include:
|
20
|
+
- cider-ci/task_components/ruby.yml
|
21
|
+
- cider-ci/task_components/bundle.yml
|
22
|
+
- cider-ci/task_components/rspec.yml
|
23
|
+
|
24
|
+
tasks:
|
25
|
+
all-rspec:
|
26
|
+
name: All rspec tests, using ActiveSupport v5
|
@@ -1,5 +1,5 @@
|
|
1
|
-
rspec:
|
2
|
-
name: 'rspec'
|
1
|
+
rspec-active-support-latest:
|
2
|
+
name: 'rspec with ActiveSupport latest'
|
3
3
|
|
4
4
|
run_when:
|
5
5
|
'some HEAD has been updated':
|
@@ -21,4 +21,4 @@ rspec:
|
|
21
21
|
|
22
22
|
tasks:
|
23
23
|
all-rspec:
|
24
|
-
name: All rspec tests
|
24
|
+
name: All rspec tests, using ActiveSupport latest
|
@@ -17,13 +17,12 @@ scripts:
|
|
17
17
|
set -eux
|
18
18
|
mkdir -p tmp/cache
|
19
19
|
export PATH=~/.rubies/$RUBY/bin:$PATH
|
20
|
-
bundle exec rspec
|
20
|
+
if [ ! -z ${ACTIVESUPPORT:-} ]; then BUNDLE_GEMFILE=Gemfile.activesupport$ACTIVESUPPORT bundle exec rspec; else bundle exec rspec; fi
|
21
21
|
|
22
22
|
start_when:
|
23
23
|
'bundled':
|
24
24
|
script_key: bundle
|
25
25
|
|
26
|
-
|
27
26
|
trial_attachments:
|
28
27
|
logs:
|
29
28
|
include_match: log\/.*\.log$
|
data/lhs.gemspec
CHANGED
@@ -20,9 +20,8 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.requirements << 'Ruby >= 2.0.0'
|
21
21
|
s.required_ruby_version = '>= 2.0.0'
|
22
22
|
|
23
|
-
s.add_dependency 'lhc', '>=
|
24
|
-
s.add_dependency '
|
25
|
-
s.add_dependency 'activesupport', '> 4'
|
23
|
+
s.add_dependency 'lhc', '>= 5.0.2'
|
24
|
+
s.add_dependency 'activesupport', '> 4.2'
|
26
25
|
|
27
26
|
s.add_development_dependency 'rspec-rails', '>= 3.0.0'
|
28
27
|
s.add_development_dependency 'rails', '>= 4.0.0'
|
data/lib/lhs.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'lhc'
|
2
|
+
Dir[File.dirname(__FILE__) + '/lhs/concerns/lhs/*.rb'].sort.each { |file| require file }
|
2
3
|
|
3
4
|
module LHS
|
5
|
+
include Configuration
|
4
6
|
class RequireLhsRecords
|
5
7
|
def initialize(app)
|
6
8
|
@app = app
|
@@ -19,7 +21,13 @@ module LHS
|
|
19
21
|
end
|
20
22
|
end
|
21
23
|
|
22
|
-
Gem.find_files('lhs/**/*.rb')
|
24
|
+
Gem.find_files('lhs/**/*.rb')
|
25
|
+
.sort
|
26
|
+
.reject do |path|
|
27
|
+
(!defined?(Rails) && File.basename(path).include?('railtie.rb')) # don't require railtie if Rails is not around
|
28
|
+
end.each do |path|
|
29
|
+
require path
|
30
|
+
end
|
23
31
|
|
24
32
|
# Preload all the LHS::Records that are defined in app/models
|
25
33
|
class Engine < Rails::Engine
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
module LHS
|
4
|
+
module Configuration
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def config
|
9
|
+
LHS::Config.instance
|
10
|
+
end
|
11
|
+
|
12
|
+
def configure
|
13
|
+
LHS::Config.instance.reset
|
14
|
+
yield config
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -377,9 +377,23 @@ class LHS::Record
|
|
377
377
|
options[:url] = compute_url!(options[:params]) unless options.key?(:url)
|
378
378
|
merge_explicit_params!(options[:params])
|
379
379
|
options.delete(:params) if options[:params] && options[:params].empty?
|
380
|
+
inject_request_cycle_cache!(options)
|
380
381
|
options
|
381
382
|
end
|
382
383
|
|
384
|
+
# Injects options into request, that enable the LHS::Record::RequestCycleCache::Interceptor
|
385
|
+
def inject_request_cycle_cache!(options)
|
386
|
+
return unless LHS.config.request_cycle_cache_enabled
|
387
|
+
interceptors = options[:interceptors] || LHC.config.interceptors
|
388
|
+
if interceptors.include?(LHC::Caching)
|
389
|
+
# Ensure LHS::RequestCycleCache interceptor is prepend
|
390
|
+
interceptors = interceptors.unshift(LHS::Record::RequestCycleCache::Interceptor)
|
391
|
+
options[:interceptors] = interceptors
|
392
|
+
else
|
393
|
+
warn(LHS::Record::REQUEST_CYCLE_CACHE_WARNING)
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
383
397
|
# LHC supports only one error handler, merge all error handlers to one
|
384
398
|
# and reraise
|
385
399
|
def merge_error_handlers(handlers)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
class LHS::Record
|
4
|
+
|
5
|
+
module RequestCycleCache
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
REQUEST_CYCLE_CACHE_WARNING = "[WARNING] Can't enable LHS::RequestCycleCache as LHC::Caching interceptor is not enabled/configured (see https://github.com/local-ch/lhc/blob/master/docs/interceptors/caching.md#caching-interceptor)!".freeze
|
9
|
+
|
10
|
+
class Interceptor < LHC::Interceptor
|
11
|
+
|
12
|
+
VERSION = 1
|
13
|
+
CACHED_METHODS = [:get].freeze
|
14
|
+
|
15
|
+
def before_request(request)
|
16
|
+
request.options = request.options.merge({
|
17
|
+
cache: true,
|
18
|
+
cache_expires_in: 5.minutes,
|
19
|
+
cache_race_condition_ttl: 5.seconds,
|
20
|
+
cache_key: cache_key_for(request),
|
21
|
+
cached_methods: CACHED_METHODS
|
22
|
+
}.merge(request.options))
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def cache_key_for(request)
|
28
|
+
[
|
29
|
+
"LHS_REQUEST_CYCLE_CACHE(v#{VERSION})",
|
30
|
+
request.method.upcase,
|
31
|
+
[request.url, request.params.presence].compact.join('?'),
|
32
|
+
"REQUEST=#{LHS::Record::RequestCycleCache::RequestCycleThreadRegistry.request_id}",
|
33
|
+
"HEADERS=#{request.headers.hash}"
|
34
|
+
].join(' ')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
class LHS::Record
|
4
|
+
|
5
|
+
module RequestCycleCache
|
6
|
+
class RequestCycleThreadRegistry
|
7
|
+
# Using ActiveSupports PerThreadRegistry to be able to support Active Support v4.
|
8
|
+
# Will switch to thread_mattr_accessor (which comes with Activesupport) when we dropping support for Active Support v5.
|
9
|
+
extend ActiveSupport::PerThreadRegistry
|
10
|
+
attr_accessor :request_id
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/lhs/config.rb
ADDED
data/lib/lhs/railtie.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module LHS
|
2
|
+
class Railtie < Rails::Railtie
|
3
|
+
initializer "lhs.hook_into_controller_initialization" do
|
4
|
+
class ActionController::Base
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
prepare_lhs_request_cycle_cache
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def prepare_lhs_request_cycle_cache
|
14
|
+
return unless LHS.config.request_cycle_cache_enabled
|
15
|
+
LHS::Record::RequestCycleCache::RequestCycleThreadRegistry.request_id = [Time.now.to_f, request.object_id].join('#')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/lhs/record.rb
CHANGED
data/lib/lhs/version.rb
CHANGED
data/spec/autoloading_spec.rb
CHANGED
@@ -6,13 +6,13 @@ describe LHS, type: :request do
|
|
6
6
|
because it's necessary for endpoint-to-record-class-discovery",
|
7
7
|
cleanup_before: false do
|
8
8
|
all_endpoints = LHS::Record::Endpoints.all
|
9
|
-
expect(all_endpoints['
|
10
|
-
expect(all_endpoints['
|
9
|
+
expect(all_endpoints['http://datastore/v2/users']).to be
|
10
|
+
expect(all_endpoints['http://datastore/v2/users/:id']).to be
|
11
11
|
expect(
|
12
|
-
User.endpoints.detect { |endpoint| endpoint.url == '
|
12
|
+
User.endpoints.detect { |endpoint| endpoint.url == 'http://datastore/v2/users' }
|
13
13
|
).to be
|
14
14
|
expect(
|
15
|
-
User.endpoints.detect { |endpoint| endpoint.url == '
|
15
|
+
User.endpoints.detect { |endpoint| endpoint.url == 'http://datastore/v2/users/:id' }
|
16
16
|
).to be
|
17
17
|
end
|
18
18
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class RequestCycleCacheController < ApplicationController
|
2
|
+
def simple
|
3
|
+
User.find(1) # first request
|
4
|
+
user = User.find(1) # second request that should be serverd from request cycle cache
|
5
|
+
render json: user.to_json
|
6
|
+
end
|
7
|
+
|
8
|
+
def no_caching_interceptor
|
9
|
+
User.options(interceptors: []).find(1) # first request
|
10
|
+
user = User.options(interceptors: []).find(1) # second request
|
11
|
+
render json: user.to_json
|
12
|
+
end
|
13
|
+
|
14
|
+
def parallel
|
15
|
+
User.find(1, 2) # first request
|
16
|
+
users = User.find(1, 2) # second request that should be serverd from request cycle cache
|
17
|
+
render json: users.to_json
|
18
|
+
end
|
19
|
+
|
20
|
+
def headers
|
21
|
+
User.find(1) # first request
|
22
|
+
user = User.options(headers: { 'Authentication' => 'Bearer 123' }).find(1) # second request that should NOT be serverd from request cycle cache as the headers are different
|
23
|
+
render json: user.to_json
|
24
|
+
end
|
25
|
+
end
|
@@ -12,10 +12,6 @@ Rails.application.configure do
|
|
12
12
|
# preloads Rails for running tests, you may have to set it to true.
|
13
13
|
config.eager_load = false
|
14
14
|
|
15
|
-
# Configure static asset server for tests with Cache-Control for performance.
|
16
|
-
config.public_file_server.enabled = true
|
17
|
-
config.public_file_server.headers = { 'Cache-Control' => 'public, max-age=3600' }
|
18
|
-
|
19
15
|
# Show full error reports and disable caching.
|
20
16
|
config.consider_all_requests_local = true
|
21
17
|
config.action_controller.perform_caching = false
|
data/spec/dummy/config/routes.rb
CHANGED
@@ -1,56 +1,7 @@
|
|
1
1
|
Rails.application.routes.draw do
|
2
|
-
# The priority is based upon order of creation: first created -> highest priority.
|
3
|
-
# See how all your routes lay out with "rake routes".
|
4
|
-
|
5
|
-
# You can have the root of your site routed with "root"
|
6
2
|
root 'application#root'
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
# Example of named route that can be invoked with purchase_url(id: product.id)
|
12
|
-
# get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
|
13
|
-
|
14
|
-
# Example resource route (maps HTTP verbs to controller actions automatically):
|
15
|
-
# resources :products
|
16
|
-
|
17
|
-
# Example resource route with options:
|
18
|
-
# resources :products do
|
19
|
-
# member do
|
20
|
-
# get 'short'
|
21
|
-
# post 'toggle'
|
22
|
-
# end
|
23
|
-
#
|
24
|
-
# collection do
|
25
|
-
# get 'sold'
|
26
|
-
# end
|
27
|
-
# end
|
28
|
-
|
29
|
-
# Example resource route with sub-resources:
|
30
|
-
# resources :products do
|
31
|
-
# resources :comments, :sales
|
32
|
-
# resource :seller
|
33
|
-
# end
|
34
|
-
|
35
|
-
# Example resource route with more complex sub-resources:
|
36
|
-
# resources :products do
|
37
|
-
# resources :comments
|
38
|
-
# resources :sales do
|
39
|
-
# get 'recent', on: :collection
|
40
|
-
# end
|
41
|
-
# end
|
42
|
-
|
43
|
-
# Example resource route with concerns:
|
44
|
-
# concern :toggleable do
|
45
|
-
# post 'toggle'
|
46
|
-
# end
|
47
|
-
# resources :posts, concerns: :toggleable
|
48
|
-
# resources :photos, concerns: :toggleable
|
49
|
-
|
50
|
-
# Example resource route within a namespace:
|
51
|
-
# namespace :admin do
|
52
|
-
# # Directs /admin/products/* to Admin::ProductsController
|
53
|
-
# # (app/controllers/admin/products_controller.rb)
|
54
|
-
# resources :products
|
55
|
-
# end
|
3
|
+
get 'request_cycle_cache/simple' => 'request_cycle_cache#simple'
|
4
|
+
get 'request_cycle_cache/no_caching_interceptor' => 'request_cycle_cache#no_caching_interceptor'
|
5
|
+
get 'request_cycle_cache/parallel' => 'request_cycle_cache#parallel'
|
6
|
+
get 'request_cycle_cache/headers' => 'request_cycle_cache#headers'
|
56
7
|
end
|
@@ -37,7 +37,7 @@ describe LHS::Record do
|
|
37
37
|
expect(lambda {
|
38
38
|
Customer.includes(:contracts).find(1)
|
39
39
|
}).to output(
|
40
|
-
|
40
|
+
%r{\[WARNING\] You included `http://datastore/customers/1/contracts`, but this endpoint is paginated. You might want to use `includes_all` instead of `includes` \(https://github.com/local-ch/lhs#includes_all-for-paginated-endpoints\)\.}
|
41
41
|
).to_stderr
|
42
42
|
end
|
43
43
|
end
|
data/spec/record/request_spec.rb
CHANGED
@@ -13,8 +13,9 @@ describe LHS::Record do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
it 'is using params as query params explicitly when provided in params namespace' do
|
16
|
-
stub_request(:get, "#{datastore}/content-ads/123/feedbacks?campaign_id=456").to_return(status: 200)
|
17
|
-
Record.where(campaign_id: 123, params: { campaign_id: '456' })
|
16
|
+
request = stub_request(:get, "#{datastore}/content-ads/123/feedbacks?campaign_id=456").to_return(status: 200)
|
17
|
+
Record.where(campaign_id: 123, params: { campaign_id: '456' }).to_a
|
18
|
+
assert_requested(request)
|
18
19
|
end
|
19
20
|
end
|
20
21
|
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
require 'lhc/test/cache_helper.rb'
|
3
|
+
|
4
|
+
describe 'Request Cycle Cache', type: :request do
|
5
|
+
let!(:request) do
|
6
|
+
stub_request(:get, "http://datastore/v2/users/1").to_return(body: { name: 'Steve' }.to_json)
|
7
|
+
end
|
8
|
+
|
9
|
+
let!(:second_request) do
|
10
|
+
stub_request(:get, "http://datastore/v2/users/2").to_return(body: { name: 'Peter' }.to_json)
|
11
|
+
end
|
12
|
+
|
13
|
+
before(:each) do
|
14
|
+
class User < LHS::Record
|
15
|
+
endpoint 'http://datastore/v2/users'
|
16
|
+
endpoint 'http://datastore/v2/users/:id'
|
17
|
+
end
|
18
|
+
LHC.configure do |config|
|
19
|
+
config.interceptors = [LHC::Caching]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'serves requests that are exactly the same during one request cycle from the cache',
|
24
|
+
cleanup_before: false, request_cycle_cache: true do
|
25
|
+
get '/request_cycle_cache/simple'
|
26
|
+
expect(request).to have_been_made.once
|
27
|
+
|
28
|
+
# Second Request, Second Cycle, requests again
|
29
|
+
get '/request_cycle_cache/simple'
|
30
|
+
expect(request).to have_been_made.times(2)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'does not serve from request cycle cache when cache interceptor is not hooked in, but logs a warning',
|
34
|
+
cleanup_before: false, request_cycle_cache: true do
|
35
|
+
expect(lambda do
|
36
|
+
get '/request_cycle_cache/no_caching_interceptor'
|
37
|
+
end).to output(
|
38
|
+
%r{\[WARNING\] Can't enable LHS::RequestCycleCache as LHC::Caching interceptor is not enabled/configured \(see https://github.com/local-ch/lhc/blob/master/docs/interceptors/caching.md#caching-interceptor\)!}
|
39
|
+
).to_stderr
|
40
|
+
expect(request).to have_been_made.times(2)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'serves requests also from cache when LHS/LHC makes requests in parallel',
|
44
|
+
cleanup_before: false, request_cycle_cache: true do
|
45
|
+
get '/request_cycle_cache/parallel'
|
46
|
+
expect(request).to have_been_made.once
|
47
|
+
expect(second_request).to have_been_made.once
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'sets different uniq request ids as base for request cycle caching for different requests',
|
51
|
+
cleanup_before: false, request_cycle_cache: true do
|
52
|
+
get '/request_cycle_cache/simple'
|
53
|
+
first_request_id = LHS::Record::RequestCycleCache::RequestCycleThreadRegistry.request_id
|
54
|
+
second_request_id = nil
|
55
|
+
thread = Thread.new do
|
56
|
+
get '/request_cycle_cache/simple'
|
57
|
+
second_request_id = LHS::Record::RequestCycleCache::RequestCycleThreadRegistry.request_id
|
58
|
+
end
|
59
|
+
thread.join
|
60
|
+
expect(first_request_id).not_to be_nil
|
61
|
+
expect(second_request_id).not_to be_nil
|
62
|
+
expect(first_request_id).not_to eq second_request_id
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'disabled request cycle cache' do
|
66
|
+
it 'does not serve from request cycle cache when cache interceptor is not hooked in, and does not warn if request cycle cache is explicitly disabled',
|
67
|
+
cleanup_before: false do
|
68
|
+
expect(lambda do
|
69
|
+
get '/request_cycle_cache/no_caching_interceptor'
|
70
|
+
end).not_to output(
|
71
|
+
%r{\[WARNING\] Can't enable LHS::RequestCycleCache as LHC::Caching interceptor is not enabled/configured \(see https://github.com/local-ch/lhc/blob/master/docs/interceptors/caching.md#caching-interceptor\)!}
|
72
|
+
).to_stderr
|
73
|
+
expect(request).to have_been_made.times(2)
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'DOES NOT serve requests that are exactly the same during one request cycle from the cache, when request cycle cache is disabled',
|
77
|
+
cleanup_before: false do
|
78
|
+
get '/request_cycle_cache/simple'
|
79
|
+
expect(request).to have_been_made.times(2)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'headers' do
|
84
|
+
it 'considers the request headers when setting the cache key',
|
85
|
+
cleanup_before: false, request_cycle_cache: true do
|
86
|
+
get '/request_cycle_cache/headers'
|
87
|
+
expect(request).to have_been_made.times(2)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lhs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 11.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- https://github.com/local-ch/lhs/graphs/contributors
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: lhc
|
@@ -16,42 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 5.0.2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: lhc-core-interceptors
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 2.0.1
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 2.0.1
|
26
|
+
version: 5.0.2
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: activesupport
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
31
|
- - ">"
|
46
32
|
- !ruby/object:Gem::Version
|
47
|
-
version: '4'
|
33
|
+
version: '4.2'
|
48
34
|
type: :runtime
|
49
35
|
prerelease: false
|
50
36
|
version_requirements: !ruby/object:Gem::Requirement
|
51
37
|
requirements:
|
52
38
|
- - ">"
|
53
39
|
- !ruby/object:Gem::Version
|
54
|
-
version: '4'
|
40
|
+
version: '4.2'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: rspec-rails
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -177,13 +163,17 @@ files:
|
|
177
163
|
- ".rubocop.yml"
|
178
164
|
- ".ruby-version"
|
179
165
|
- Gemfile
|
166
|
+
- Gemfile.activesupport4
|
167
|
+
- Gemfile.activesupport5
|
180
168
|
- README.md
|
181
169
|
- Rakefile
|
182
170
|
- cider-ci.yml
|
183
171
|
- cider-ci/bin/bundle
|
184
172
|
- cider-ci/bin/ruby_install
|
185
173
|
- cider-ci/bin/ruby_version
|
186
|
-
- cider-ci/jobs/rspec.yml
|
174
|
+
- cider-ci/jobs/rspec-activesupport-4.yml
|
175
|
+
- cider-ci/jobs/rspec-activesupport-5.yml
|
176
|
+
- cider-ci/jobs/rspec-activesupport-latest.yml
|
187
177
|
- cider-ci/jobs/rubocop.yml
|
188
178
|
- cider-ci/task_components/bundle.yml
|
189
179
|
- cider-ci/task_components/rspec.yml
|
@@ -202,6 +192,7 @@ files:
|
|
202
192
|
- lib/lhs/concerns/item/save.rb
|
203
193
|
- lib/lhs/concerns/item/update.rb
|
204
194
|
- lib/lhs/concerns/item/validation.rb
|
195
|
+
- lib/lhs/concerns/lhs/configuration.rb
|
205
196
|
- lib/lhs/concerns/proxy/accessors.rb
|
206
197
|
- lib/lhs/concerns/proxy/create.rb
|
207
198
|
- lib/lhs/concerns/proxy/link.rb
|
@@ -219,7 +210,10 @@ files:
|
|
219
210
|
- lib/lhs/concerns/record/model.rb
|
220
211
|
- lib/lhs/concerns/record/pagination.rb
|
221
212
|
- lib/lhs/concerns/record/request.rb
|
213
|
+
- lib/lhs/concerns/record/request_cycle_cache/interceptor.rb
|
214
|
+
- lib/lhs/concerns/record/request_cycle_cache/request_cycle_thread_registry.rb
|
222
215
|
- lib/lhs/concerns/record/scope.rb
|
216
|
+
- lib/lhs/config.rb
|
223
217
|
- lib/lhs/data.rb
|
224
218
|
- lib/lhs/endpoint.rb
|
225
219
|
- lib/lhs/errors.rb
|
@@ -229,6 +223,7 @@ files:
|
|
229
223
|
- lib/lhs/pagination/page.rb
|
230
224
|
- lib/lhs/pagination/start.rb
|
231
225
|
- lib/lhs/proxy.rb
|
226
|
+
- lib/lhs/railtie.rb
|
232
227
|
- lib/lhs/record.rb
|
233
228
|
- lib/lhs/version.rb
|
234
229
|
- script/ci/build.sh
|
@@ -262,6 +257,7 @@ files:
|
|
262
257
|
- spec/dummy/app/assets/stylesheets/application.css
|
263
258
|
- spec/dummy/app/controllers/application_controller.rb
|
264
259
|
- spec/dummy/app/controllers/concerns/.keep
|
260
|
+
- spec/dummy/app/controllers/request_cycle_cache_controller.rb
|
265
261
|
- spec/dummy/app/helpers/application_helper.rb
|
266
262
|
- spec/dummy/app/mailers/.keep
|
267
263
|
- spec/dummy/app/models/.keep
|
@@ -284,7 +280,6 @@ files:
|
|
284
280
|
- spec/dummy/config/initializers/cookies_serializer.rb
|
285
281
|
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
286
282
|
- spec/dummy/config/initializers/inflections.rb
|
287
|
-
- spec/dummy/config/initializers/lhc.rb
|
288
283
|
- spec/dummy/config/initializers/mime_types.rb
|
289
284
|
- spec/dummy/config/initializers/session_store.rb
|
290
285
|
- spec/dummy/config/initializers/wrap_parameters.rb
|
@@ -359,12 +354,14 @@ files:
|
|
359
354
|
- spec/record/where_chains_spec.rb
|
360
355
|
- spec/record/where_spec.rb
|
361
356
|
- spec/record/where_values_hash_spec.rb
|
357
|
+
- spec/request_cycle_cache/main_spec.rb
|
362
358
|
- spec/spec_helper.rb
|
363
359
|
- spec/support/cleanup.rb
|
364
360
|
- spec/support/fixtures/json/feedback.json
|
365
361
|
- spec/support/fixtures/json/feedbacks.json
|
366
362
|
- spec/support/fixtures/json/localina_content_ad.json
|
367
363
|
- spec/support/load_json.rb
|
364
|
+
- spec/support/request_cycle_cache.rb
|
368
365
|
- spec/views/form_for_spec.rb
|
369
366
|
homepage: https://github.com/local-ch/lhs
|
370
367
|
licenses:
|
@@ -387,7 +384,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
387
384
|
requirements:
|
388
385
|
- Ruby >= 2.0.0
|
389
386
|
rubyforge_project:
|
390
|
-
rubygems_version: 2.
|
387
|
+
rubygems_version: 2.6.8
|
391
388
|
signing_key:
|
392
389
|
specification_version: 4
|
393
390
|
summary: Rails gem providing an easy, active-record-like interface for http json services
|
@@ -421,6 +418,7 @@ test_files:
|
|
421
418
|
- spec/dummy/app/assets/stylesheets/application.css
|
422
419
|
- spec/dummy/app/controllers/application_controller.rb
|
423
420
|
- spec/dummy/app/controllers/concerns/.keep
|
421
|
+
- spec/dummy/app/controllers/request_cycle_cache_controller.rb
|
424
422
|
- spec/dummy/app/helpers/application_helper.rb
|
425
423
|
- spec/dummy/app/mailers/.keep
|
426
424
|
- spec/dummy/app/models/.keep
|
@@ -443,7 +441,6 @@ test_files:
|
|
443
441
|
- spec/dummy/config/initializers/cookies_serializer.rb
|
444
442
|
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
445
443
|
- spec/dummy/config/initializers/inflections.rb
|
446
|
-
- spec/dummy/config/initializers/lhc.rb
|
447
444
|
- spec/dummy/config/initializers/mime_types.rb
|
448
445
|
- spec/dummy/config/initializers/session_store.rb
|
449
446
|
- spec/dummy/config/initializers/wrap_parameters.rb
|
@@ -518,10 +515,12 @@ test_files:
|
|
518
515
|
- spec/record/where_chains_spec.rb
|
519
516
|
- spec/record/where_spec.rb
|
520
517
|
- spec/record/where_values_hash_spec.rb
|
518
|
+
- spec/request_cycle_cache/main_spec.rb
|
521
519
|
- spec/spec_helper.rb
|
522
520
|
- spec/support/cleanup.rb
|
523
521
|
- spec/support/fixtures/json/feedback.json
|
524
522
|
- spec/support/fixtures/json/feedbacks.json
|
525
523
|
- spec/support/fixtures/json/localina_content_ad.json
|
526
524
|
- spec/support/load_json.rb
|
525
|
+
- spec/support/request_cycle_cache.rb
|
527
526
|
- spec/views/form_for_spec.rb
|