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