faraday-manual-cache 0.1.1 → 0.4.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
- SHA1:
3
- metadata.gz: a68b0911c029cdb80405cae43fee9559e976d7bb
4
- data.tar.gz: 64f2279973047eb744398526cf3ce5a62f541c0f
2
+ SHA256:
3
+ metadata.gz: 5687d1ea9b8a6e476067698ee92e5ad59249d6744589d97d2ccfd7f0ddc17447
4
+ data.tar.gz: 8a90c333880ef44bc400347f76e44121628c43fe4ec4a7d7b3adfa1d537c9391
5
5
  SHA512:
6
- metadata.gz: 2b54c26beca7332c2bcd52bd5f2c0d504e43187ce3c6f52f8e48f508063155ca4f349f0a2dda20090789afdd6a4ec52ab106afa3076ab466bfd309c21d8776db
7
- data.tar.gz: 0a9c7c49bddc69c01d6243f9e1c102bc221ad771a74f288bdf917023481e9daf64491fa154aa5c53dcb3af7655d34e90f6e742330d184b906ff9227ada5e782b
6
+ metadata.gz: bc1dbefa346aa1999e4491abfe42a575b9670d9861656f2728670a404f062056e5f76e5f70ff4e9969bed5452f51d8428a2dac7cef38ea600dd518de6cd6d7d8
7
+ data.tar.gz: cd7847c0c26d2a9eb0f3427901555bf0114db9c37fb10512c0fc7cb86b58a961551766efda5f5d09cb69c819d32feb355a27f9056965b0a7f87568e0b5fdcd04
@@ -0,0 +1,9 @@
1
+ version: 2
2
+ jobs:
3
+ build:
4
+ docker:
5
+ - image: circleci/ruby:2.4.1
6
+ steps:
7
+ - checkout
8
+ - run: bundle install
9
+ - run: bundle exec rspec --color --require spec_helper spec --format progress
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/README.md CHANGED
@@ -18,9 +18,19 @@ Or install it yourself as:
18
18
 
19
19
  $ gem install faraday-manual-cache
20
20
 
21
+ ## Configuration
22
+
23
+ Create a configuration file and select your memory store class. If you use Rails, just create an initializator.
24
+
25
+ ```ruby
26
+ FaradayManualCache.configure do |config|
27
+ config.memory_store = ActiveSupport::Cache::MemoryStore.new
28
+ end
29
+ ```
30
+
21
31
  ## Usage
22
32
 
23
- Super simple example that caches using the default store (`MemoryStore`) for the default expires_in (30 seconds):
33
+ Super simple example that caches using the default store (`MemoryStore`) for the default expires_in (30 seconds):
24
34
 
25
35
  ```ruby
26
36
  require 'faraday'
@@ -33,29 +43,29 @@ end
33
43
  ```
34
44
  The middleware currently takes several options:
35
45
 
46
+ * `conditions`: Conditional caching (default GET and HEAD requests).
47
+ * `cache_key`: Key for requests comparison (default URL)
36
48
  * `expires_in`: Cache expiry, in seconds (default 30).
37
- * `store`: The `ActiveSupport::Cache`-compatible store to use (default `ActiveSupport::Cache::MemoryStore`).
38
- * `store_options`: Options passed to the store if created by lookup (e.g. when specifying `:memory_store`, `:redis_store`, etc).
49
+ * `logger`: Specify a logger to enable logging.
39
50
 
40
51
  So a more complicated example would be:
41
52
 
42
53
  ```ruby
43
54
  require 'faraday'
44
55
  require 'faraday-manual-cache'
45
- require 'redis-rails'
46
56
 
47
57
  connection = Faraday.new(url: 'http://example.com') do |builder|
48
- builder.use :manual_cache, expires_in: 10, store: :redis_store, store_options: { host: 'my-redis-server', port: '1234' }
58
+ builder.use :manual_cache,
59
+ conditions: ->(env) { env.method == :get },
60
+ cache_key: ->(env) { "prefix-#{env.url}" },
61
+ expires_in: 10,
62
+ logger: Rails.logger
49
63
  builder.adapter Faraday.default_adapter
50
64
  end
51
65
  ```
52
66
 
53
67
  As with `faraday-http-cache` it's recommended that `faraday-manual-cache` be fairly low in the middleware stack.
54
68
 
55
- ## TODO
56
-
57
- * Additional cache key options.
58
-
59
69
  ## Contributing
60
70
 
61
71
  1. Fork it ( http://github.com/dobs/faraday-manual-cache/fork )
@@ -70,4 +80,4 @@ Some implementation details taken from [`faraday-http-cache`](https://github.com
70
80
 
71
81
  ## Contributors
72
82
 
73
- * Maintainer: [Daniel O'Brien](http://github.com/dobs)
83
+ * Maintainer: [Daniel O'Brien](http://github.com/dobs)
@@ -1,7 +1,10 @@
1
1
  # coding: utf-8
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require 'faraday-manual-cache/version'
4
+
2
5
  Gem::Specification.new do |spec|
3
6
  spec.name = 'faraday-manual-cache'
4
- spec.version = '0.1.1'
7
+ spec.version = FaradayManualCache::VERSION
5
8
  spec.authors = ['Daniel O\'Brien']
6
9
  spec.email = ['dan@dobs.org']
7
10
  spec.summary = %q(A super simple Faraday cache implementation.)
@@ -21,4 +24,5 @@ Gem::Specification.new do |spec|
21
24
 
22
25
  spec.add_development_dependency 'bundler', '~> 1.5'
23
26
  spec.add_development_dependency 'rake'
27
+ spec.add_development_dependency 'rspec'
24
28
  end
@@ -0,0 +1,18 @@
1
+ module FaradayManualCache
2
+ class << self
3
+ attr_accessor :configuration
4
+ end
5
+
6
+ def self.configure
7
+ self.configuration ||= Configuration.new
8
+ yield(configuration)
9
+ end
10
+
11
+ class Configuration
12
+ attr_accessor :memory_store
13
+
14
+ def initialize
15
+ @memory_store = ActiveSupport::Cache::MemoryStore.new
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ module FaradayManualCache
2
+ VERSION = '0.4.0'.freeze
3
+ end
@@ -1,3 +1,4 @@
1
+ require 'faraday-manual-cache/configuration'
1
2
  require 'faraday'
2
3
 
3
4
  module Faraday
@@ -8,26 +9,22 @@ module Faraday
8
9
  #
9
10
  # Currently accepts four arguments:
10
11
  #
12
+ # :conditions - Conditional caching based on a lambda (default: GET/HEAD
13
+ # requests)
11
14
  # :expires_in - Cache expiry, in seconds (default: 30).
12
15
  # :logger - A logger object to send cache hit/miss/write messages.
13
- # :store - An object (or lookup symbol) for an
14
- # ActiveSupport::Cache::Store instance. (default:
15
- # MemoryStore).
16
- # :store_options - Options to pass to the store when generated based on a
17
- # lookup symvol (default: {}).
16
+
18
17
  class ManualCache < Faraday::Middleware
18
+ DEFAULT_CONDITIONS = ->(env) { env.method == :get || env.method == :head }
19
+ DEFAULT_CACHE_KEY = ->(env) { env.url }
20
+
19
21
  def initialize(app, *args)
20
22
  super(app)
21
23
  options = args.first || {}
24
+ @conditions = options.fetch(:conditions, DEFAULT_CONDITIONS)
22
25
  @expires_in = options.fetch(:expires_in, 30)
23
26
  @logger = options.fetch(:logger, nil)
24
- @namespace = options.fetch(:namespace, 'faraday-manual-cache')
25
- @store = options.fetch(:store, :memory_store)
26
- @store_options = options.fetch(:store_options, {})
27
-
28
- @store_options[:namespace] ||= @namespace
29
-
30
- initialize_store
27
+ @cache_key = options.fetch(:cache_key, DEFAULT_CACHE_KEY)
31
28
  end
32
29
 
33
30
  def call(env)
@@ -41,7 +38,7 @@ module Faraday
41
38
 
42
39
  if response_env
43
40
  response_env.response_headers['x-faraday-manual-cache'] = 'HIT'
44
- to_response(cached_response(env))
41
+ to_response(response_env)
45
42
  else
46
43
  @app.call(env).on_complete do |response_env|
47
44
  response_env.response_headers['x-faraday-manual-cache'] = 'MISS'
@@ -54,20 +51,28 @@ module Faraday
54
51
  return unless cacheable?(env) && !env.request_headers['x-faraday-manual-cache']
55
52
 
56
53
  info "Cache WRITE: #{key(env)}"
57
- @store.write(key(env), env, expires_in: @expires_in)
54
+ store.write(
55
+ key(env),
56
+ env,
57
+ expires_in: expires_in(env)
58
+ )
58
59
  end
59
60
 
60
61
  def cacheable?(env)
61
- env.method == :get || env.method == :head
62
+ @conditions.call(env)
62
63
  end
63
64
 
64
65
  def cached_response(env)
65
- response_env = @store.fetch(key(env)) if cacheable?(env) && !env.request_headers['x-faraday-manual-cache']
66
+ if cacheable?(env) && !env.request_headers['x-faraday-manual-cache']
67
+ response_env = store.fetch(key(env))
68
+ end
69
+
66
70
  if response_env
67
71
  info "Cache HIT: #{key(env)}"
68
72
  else
69
73
  info "Cache MISS: #{key(env)}"
70
74
  end
75
+
71
76
  response_env
72
77
  end
73
78
 
@@ -76,14 +81,15 @@ module Faraday
76
81
  end
77
82
 
78
83
  def key(env)
79
- env.url
84
+ @cache_key.call(env)
80
85
  end
81
86
 
82
- def initialize_store
83
- return unless @store.is_a? Symbol
87
+ def expires_in(env)
88
+ @expires_in.respond_to?(:call) ? @expires_in.call(env) : @expires_in
89
+ end
84
90
 
85
- require 'active_support/cache'
86
- @store = ActiveSupport::Cache.lookup_store(@store, @store_options)
91
+ def store
92
+ @store ||= FaradayManualCache.configuration.memory_store
87
93
  end
88
94
 
89
95
  def to_response(env)
@@ -0,0 +1,126 @@
1
+ require 'faraday'
2
+ require 'faraday-manual-cache'
3
+ require 'active_support'
4
+
5
+ class MockStore
6
+ def fetch(*args) end
7
+ def write(*args) end
8
+ end
9
+
10
+ RSpec.describe Faraday::ManualCache do
11
+ let(:stubs) do
12
+ Faraday::Adapter::Test::Stubs.new do |stub|
13
+ stub.get('/') { |_| [200, {}, ''] }
14
+ stub.head('/') { |_| [200, {}, ''] }
15
+ stub.post('/') { |_| [200, {}, ''] }
16
+ stub.put('/') { |_| [200, {}, ''] }
17
+ end
18
+ end
19
+ let(:store) { ActiveSupport::Cache::MemoryStore.new }
20
+ let(:configuration_double) { double(:configuration_double, memory_store: store) }
21
+
22
+ before do
23
+ allow(FaradayManualCache).to receive(:configuration).and_return(configuration_double)
24
+ end
25
+
26
+ context 'basic configuration' do
27
+ subject do
28
+ Faraday.new(url: 'http://www.example.com') do |faraday|
29
+ faraday.use :manual_cache
30
+ faraday.adapter :test, stubs
31
+ end
32
+ end
33
+
34
+ it 'should cache on GET' do
35
+ expect(store).to receive(:fetch)
36
+ expect(store).to receive(:write)
37
+ subject.get('/')
38
+ end
39
+
40
+ it 'should cache on HEAD' do
41
+ expect(store).to receive(:fetch)
42
+ expect(store).to receive(:write)
43
+ subject.head('/')
44
+ end
45
+
46
+ it 'should not cache on POST' do
47
+ expect(store).not_to receive(:fetch)
48
+ expect(store).not_to receive(:write)
49
+ subject.post('/')
50
+ end
51
+
52
+ it 'should not cache on PUT' do
53
+ expect(store).not_to receive(:fetch)
54
+ expect(store).not_to receive(:write)
55
+ subject.put('/')
56
+ end
57
+ end
58
+
59
+ context 'conditional configuration' do
60
+ subject do
61
+ Faraday.new(url: 'http://www.example.com') do |faraday|
62
+ faraday.use :manual_cache, conditions: ->(_) { true }
63
+ faraday.adapter :test, stubs
64
+ end
65
+ end
66
+
67
+ it 'should cache on GET' do
68
+ expect(store).to receive(:fetch)
69
+ expect(store).to receive(:write)
70
+ subject.get('/')
71
+ end
72
+
73
+ it 'should cache on HEAD' do
74
+ expect(store).to receive(:fetch)
75
+ expect(store).to receive(:write)
76
+ subject.head('/')
77
+ end
78
+
79
+ it 'should cache on POST' do
80
+ expect(store).to receive(:fetch)
81
+ expect(store).to receive(:write)
82
+ subject.post('/')
83
+ end
84
+
85
+ it 'should cache on PUT' do
86
+ expect(store).to receive(:fetch)
87
+ expect(store).to receive(:write)
88
+ subject.put('/')
89
+ end
90
+ end
91
+
92
+ context 'conditional configuration with cache key' do
93
+ subject do
94
+ Faraday.new(url: 'http://www.example.com') do |faraday|
95
+ faraday.use :manual_cache,
96
+ conditions: ->(_) { true },
97
+ cache_key: ->(env) { "prefix-#{env.url}" }
98
+ faraday.adapter :test, stubs
99
+ end
100
+ end
101
+
102
+ it 'should cache based of cache_key' do
103
+ expect(store).to receive(:fetch)
104
+ expect(store).to receive(:write).with('prefix-http://www.example.com/', any_args)
105
+ subject.get('/')
106
+ end
107
+ end
108
+
109
+ context 'dynamic configuration with expires in' do
110
+ subject do
111
+ Faraday.new(url: 'http://www.example.com') do |faraday|
112
+ faraday.use :manual_cache,
113
+ conditions: ->(_) { true },
114
+ cache_key: ->(env) { "prefix-#{env.url}" },
115
+ expires_in: ->(env) { env.status * 2 }
116
+ faraday.adapter :test, stubs
117
+ end
118
+ end
119
+
120
+ it 'should cache with ttl based on lambda' do
121
+ expect(store).to receive(:fetch)
122
+ expect(store).to receive(:write).with('prefix-http://www.example.com/', any_args, expires_in: 400)
123
+ subject.get('/')
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,20 @@
1
+ RSpec.configure do |config|
2
+ config.expect_with :rspec do |expectations|
3
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
4
+ end
5
+
6
+ config.mock_with :rspec do |mocks|
7
+ mocks.verify_partial_doubles = true
8
+ end
9
+
10
+ config.shared_context_metadata_behavior = :apply_to_host_groups
11
+ config.filter_run_when_matching :focus
12
+ config.disable_monkey_patching!
13
+
14
+ if config.files_to_run.one?
15
+ config.default_formatter = 'doc'
16
+ end
17
+
18
+ config.order = :random
19
+ Kernel.srand config.seed
20
+ end
metadata CHANGED
@@ -1,69 +1,83 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faraday-manual-cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel O'Brien
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-25 00:00:00.000000000 Z
11
+ date: 2019-02-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 3.0.0
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
26
  version: 3.0.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: faraday
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0.9'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.9'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '1.5'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.5'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
69
83
  description: A super simple Faraday cache implementation.
@@ -73,15 +87,21 @@ executables: []
73
87
  extensions: []
74
88
  extra_rdoc_files: []
75
89
  files:
76
- - .gitignore
77
- - .rubocop.yml
90
+ - ".circleci/config.yml"
91
+ - ".gitignore"
92
+ - ".rspec"
93
+ - ".rubocop.yml"
78
94
  - Gemfile
79
95
  - LICENSE.txt
80
96
  - README.md
81
97
  - Rakefile
82
98
  - faraday-manual-cache.gemspec
83
99
  - lib/faraday-manual-cache.rb
100
+ - lib/faraday-manual-cache/configuration.rb
101
+ - lib/faraday-manual-cache/version.rb
84
102
  - lib/faraday/manual_cache.rb
103
+ - spec/manual_cache_spec.rb
104
+ - spec/spec_helper.rb
85
105
  homepage: https://github.com/dobs/faraday-manual-cache
86
106
  licenses:
87
107
  - MIT
@@ -92,18 +112,20 @@ require_paths:
92
112
  - lib
93
113
  required_ruby_version: !ruby/object:Gem::Requirement
94
114
  requirements:
95
- - - '>='
115
+ - - ">="
96
116
  - !ruby/object:Gem::Version
97
117
  version: '1.9'
98
118
  required_rubygems_version: !ruby/object:Gem::Requirement
99
119
  requirements:
100
- - - '>='
120
+ - - ">="
101
121
  - !ruby/object:Gem::Version
102
122
  version: '0'
103
123
  requirements: []
104
124
  rubyforge_project:
105
- rubygems_version: 2.0.3
125
+ rubygems_version: 2.7.8
106
126
  signing_key:
107
127
  specification_version: 4
108
128
  summary: A super simple Faraday cache implementation.
109
- test_files: []
129
+ test_files:
130
+ - spec/manual_cache_spec.rb
131
+ - spec/spec_helper.rb