lhs 10.1.1 → 11.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d731571239e67a0d0debebd692bce21a6082df6f
4
- data.tar.gz: 43fb5ba6cf39fd0bec77356b882f345003edd7e5
3
+ metadata.gz: 47b77a705ee21920e7c48515fdf200b60bb2be61
4
+ data.tar.gz: d85c7e29b814b6ddda3c0729c1adfb405cc6e873
5
5
  SHA512:
6
- metadata.gz: 9bc0b8b031eb8dd7da567ff0df100467bb9bef7ce48260a88d1814e8552aab1f2f52767abb037ccd04ebde3e5de8949123b423b8d3e06a908b949c9d1291f51a
7
- data.tar.gz: 7a35a18d6a5776cb5186f4119f3b97c897aa590b022c6278f5b96a0d09f2d6c742ede1dfa94903382d8a285085cbb55db2f9770ca08d8e48e0bcedcbfd8dc2ae
6
+ metadata.gz: 6351281d1b7f3d3c5cc08fe91ac35f6a747d6ffa543a41b9a6737e2634bc714fe1a340453ab887030af652063afdd3305c4da811ef1bafaab8acb89ba0cd12bf
7
+ data.tar.gz: 8aef3ee080ad5d7b6d0937138434ab2758b3941dfdfcc4fddbc38beb5a1dc16507b2929a4069dbc8ee5fbb09c4a59757a1adbfc3f1bab0cb23f8644fa43f0cf1
data/.gitignore CHANGED
@@ -24,6 +24,7 @@ config/secrets.yml
24
24
 
25
25
  # these should all be checked in to normalise the environment:
26
26
  Gemfile.lock
27
+ Gemfile.*.lock
27
28
  .ruby-gemset
28
29
 
29
30
  # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org/'
2
+
3
+ gemspec
4
+ gem 'activesupport', '~> 4.2.0'
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org/'
2
+
3
+ gemspec
4
+ gem 'activesupport', '~> 5.0.0'
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', cache: true, cache_expires_in: 1.day
38
- endpoint ':service/v2/records/:id', cache: true, cache_expires_in: 1.day
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 uniqe record with parameters:
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
@@ -5,7 +5,6 @@ rescue LoadError
5
5
  end
6
6
 
7
7
  require 'rdoc/task'
8
-
9
8
  RDoc::Task.new(:rdoc) do |rdoc|
10
9
  rdoc.rdoc_dir = 'rdoc'
11
10
  rdoc.title = 'LHS'
@@ -23,4 +22,4 @@ rescue LoadError
23
22
  end
24
23
 
25
24
  Bundler::GemHelper.install_tasks
26
-
25
+
@@ -1,4 +1,6 @@
1
1
  jobs:
2
2
  include:
3
- - cider-ci/jobs/rspec.yml
3
+ - cider-ci/jobs/rspec-activesupport-4.yml
4
+ - cider-ci/jobs/rspec-activesupport-5.yml
5
+ - cider-ci/jobs/rspec-activesupport-latest.yml
4
6
  - cider-ci/jobs/rubocop.yml
@@ -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
- bundle install
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$
@@ -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', '>= 3.6.0'
24
- s.add_dependency 'lhc-core-interceptors', '>= 2.0.1'
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').sort.each { |path| require path }
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
@@ -0,0 +1,11 @@
1
+ require 'singleton'
2
+
3
+ class LHS::Config
4
+ include Singleton
5
+
6
+ attr_accessor :request_cycle_cache_enabled
7
+
8
+ def initialize
9
+ self.request_cycle_cache_enabled ||= true
10
+ end
11
+ end
@@ -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
@@ -16,6 +16,7 @@ class LHS::Record
16
16
  include Model
17
17
  include Pagination
18
18
  include Request
19
+ include RequestCycleCache
19
20
  include Scope
20
21
 
21
22
  delegate :_proxy, :_endpoint, :merge_raw!, :select, to: :_data
@@ -1,3 +1,3 @@
1
1
  module LHS
2
- VERSION = "10.1.1"
2
+ VERSION = "11.0.0"
3
3
  end
@@ -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[':datastore/v2/users']).to be
10
- expect(all_endpoints[':datastore/v2/users/:id']).to be
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 == ':datastore/v2/users' }
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 == ':datastore/v2/users/:id' }
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
@@ -1,4 +1,4 @@
1
1
  class User < LHS::Record
2
- endpoint ':datastore/v2/users'
3
- endpoint ':datastore/v2/users/:id'
2
+ endpoint 'http://datastore/v2/users'
3
+ endpoint 'http://datastore/v2/users/:id'
4
4
  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
@@ -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
- # Example of regular route:
9
- # get 'products/:id' => 'catalog#view'
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
- "[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).\n"
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
@@ -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
@@ -0,0 +1,7 @@
1
+ RSpec.configure do |config|
2
+ config.before(:each) do |spec|
3
+ enabled = spec.metadata.key?(:request_cycle_cache) && spec.metadata[:request_cycle_cache] == true
4
+ enabled ||= false
5
+ LHS.config.request_cycle_cache_enabled = enabled
6
+ end
7
+ 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: 10.1.1
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-03-29 00:00:00.000000000 Z
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: 3.6.0
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: 3.6.0
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.5.1
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
@@ -1,3 +0,0 @@
1
- LHC.configure do |config|
2
- config.placeholder(:datastore, 'http://datastore')
3
- end