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 +5 -5
- data/.circleci/config.yml +9 -0
- data/.rspec +2 -0
- data/README.md +20 -10
- data/faraday-manual-cache.gemspec +5 -1
- data/lib/faraday-manual-cache/configuration.rb +18 -0
- data/lib/faraday-manual-cache/version.rb +3 -0
- data/lib/faraday/manual_cache.rb +27 -21
- data/spec/manual_cache_spec.rb +126 -0
- data/spec/spec_helper.rb +20 -0
- metadata +38 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5687d1ea9b8a6e476067698ee92e5ad59249d6744589d97d2ccfd7f0ddc17447
|
4
|
+
data.tar.gz: 8a90c333880ef44bc400347f76e44121628c43fe4ec4a7d7b3adfa1d537c9391
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc1dbefa346aa1999e4491abfe42a575b9670d9861656f2728670a404f062056e5f76e5f70ff4e9969bed5452f51d8428a2dac7cef38ea600dd518de6cd6d7d8
|
7
|
+
data.tar.gz: cd7847c0c26d2a9eb0f3427901555bf0114db9c37fb10512c0fc7cb86b58a961551766efda5f5d09cb69c819d32feb355a27f9056965b0a7f87568e0b5fdcd04
|
data/.rspec
ADDED
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
|
-
* `
|
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,
|
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 =
|
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
|
data/lib/faraday/manual_cache.rb
CHANGED
@@ -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
|
-
|
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
|
-
@
|
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(
|
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
|
-
|
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
|
-
|
62
|
+
@conditions.call(env)
|
62
63
|
end
|
63
64
|
|
64
65
|
def cached_response(env)
|
65
|
-
|
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
|
84
|
+
@cache_key.call(env)
|
80
85
|
end
|
81
86
|
|
82
|
-
def
|
83
|
-
|
87
|
+
def expires_in(env)
|
88
|
+
@expires_in.respond_to?(:call) ? @expires_in.call(env) : @expires_in
|
89
|
+
end
|
84
90
|
|
85
|
-
|
86
|
-
@store
|
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
|
data/spec/spec_helper.rb
ADDED
@@ -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.
|
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:
|
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
|
-
- .
|
77
|
-
- .
|
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.
|
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
|