faraday-manual-cache 0.1.1 → 0.4.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
- 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