request_store 1.5.0 → 1.6.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
  SHA256:
3
- metadata.gz: 4940fb899c4f08b98633877ca272f29dcdd4ade30456bc87a2529d38da9385e8
4
- data.tar.gz: 8be86e88c85f7aeaa3b0ac1eee98da6b26f9c95595319fc010eb800e542eb3cf
3
+ metadata.gz: e791505be9e9e0f6f8bf0b3229cb7840f473f71fdb6a4bb7f4d7375a06d11cdf
4
+ data.tar.gz: b8866d3e58f810f96e3ea1b4ef7b4491b69cdf0bc6df06e5610c6d8f3312e8dd
5
5
  SHA512:
6
- metadata.gz: 59f193bbe4aaa3e1a13d5540840b379eadfd654f3f30ac5c9f8dcd780357f0fcc88a2a70d85f3637934a9eff9297cf4d410ceb2829a8ccdc2f6c9cf0631d1579
7
- data.tar.gz: 1727397fd735206c9260e5957a78ec9014966619024e7083d29e5ccab5b71178794a2aa1892f0801bbd4afd267a2b7a3b75728a0fc086d0575be2ac477040501
6
+ metadata.gz: c76ab30766f74dda033ce70567b47df54128775dca712737a946a0c5263a7c668f3e039941efda725749070bc93745f7654f62cdccd695004f4dd84852fcb930
7
+ data.tar.gz: 771cc8e824566de385f8d266fe233ea43313dac648bc4d9fbbf8b7e2fe0e1cdabfc5c0633dc09c386a2966e4cccd978dc3e37d38f135574832919641861f29af
@@ -0,0 +1,33 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+
6
+ push:
7
+ branches: [master]
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ ruby:
15
+ - 3.0
16
+ - 3.1
17
+ - 3.2
18
+ - 3.3
19
+ - ruby-head
20
+ - jruby-9.1
21
+ - jruby-9.2
22
+ - jruby-9.3
23
+ - jruby-head
24
+ - truffleruby-head
25
+
26
+ steps:
27
+ - uses: actions/checkout@v1
28
+ - uses: ruby/setup-ruby@v1
29
+ with:
30
+ ruby-version: ${{ matrix.ruby }}
31
+ bundler-cache: true # 'bundle install' and cache
32
+ - name: Test
33
+ run: bundle exec rake
data/Gemfile CHANGED
@@ -2,3 +2,12 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in request_store.gemspec
4
4
  gemspec
5
+
6
+ case Gem::Version.new(RUBY_VERSION.dup)
7
+ when ->(ruby_version) { ruby_version >= Gem::Version.new('2.2.0') }
8
+ gem 'rake', '~> 13'
9
+ when ->(ruby_version) { ruby_version >= Gem::Version.new('2.0.0') }
10
+ gem 'rake', '~> 12.3.3'
11
+ else
12
+ gem 'rake', '~> 11'
13
+ end
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # RequestStore [![build status](https://travis-ci.org/steveklabnik/request_store.svg?branch=master)](https://travis-ci.org/steveklabnik/request_store) [![Code Climate](https://codeclimate.com/github/steveklabnik/request_store.svg)](https://codeclimate.com/github/steveklabnik/request_store)
1
+ # RequestStore [![CI](https://github.com/steveklabnik/request_store/actions/workflows/ci.yml/badge.svg)](https://github.com/steveklabnik/request_store/actions/workflows/ci.yml) [![Code Climate](https://codeclimate.com/github/steveklabnik/request_store.svg)](https://codeclimate.com/github/steveklabnik/request_store)
2
2
 
3
3
  Ever needed to use a global variable in Rails? Ugh, that's the worst. If you
4
4
  need global state, you've probably reached for `Thread.current`. Like this:
@@ -58,6 +58,16 @@ Yep, everywhere you used `Thread.current` just change it to
58
58
  `RequestStore.store`. Now no matter what server you use, you'll get `1` every
59
59
  time: the storage is local to that request.
60
60
 
61
+ ### API
62
+
63
+ The `fetch` method returns the stored value if it already exists. If no stored value exists, it uses the provided block to add a new stored value.
64
+
65
+ ```ruby
66
+ top_posts = RequestStore.fetch(:top_posts) do
67
+ # code to obtain the top posts
68
+ end
69
+ ```
70
+
61
71
  ### Rails 2 compatibility
62
72
 
63
73
  The gem includes a Railtie that will configure everything properly for Rails 3+
@@ -16,12 +16,16 @@ module RequestStore
16
16
  def call(env)
17
17
  RequestStore.begin!
18
18
 
19
- response = @app.call(env)
19
+ status, headers, body = @app.call(env)
20
20
 
21
- returned = response << Rack::BodyProxy.new(response.pop) do
21
+ body = Rack::BodyProxy.new(body) do
22
22
  RequestStore.end!
23
23
  RequestStore.clear!
24
24
  end
25
+
26
+ returned = true
27
+
28
+ [status, headers, body]
25
29
  ensure
26
30
  unless returned
27
31
  RequestStore.end!
@@ -1,3 +1,3 @@
1
1
  module RequestStore
2
- VERSION = "1.5.0"
2
+ VERSION = "1.6.0"
3
3
  end
data/lib/request_store.rb CHANGED
@@ -3,28 +3,38 @@ require "request_store/middleware"
3
3
  require "request_store/railtie" if defined?(Rails::Railtie)
4
4
 
5
5
  module RequestStore
6
+ if Fiber.respond_to?(:[])
7
+ def self.scope
8
+ Fiber
9
+ end
10
+ else
11
+ def self.scope
12
+ Thread.current
13
+ end
14
+ end
15
+
6
16
  def self.store
7
- Thread.current[:request_store] ||= {}
17
+ scope[:request_store] ||= {}
8
18
  end
9
19
 
10
20
  def self.store=(store)
11
- Thread.current[:request_store] = store
21
+ scope[:request_store] = store
12
22
  end
13
23
 
14
24
  def self.clear!
15
- Thread.current[:request_store] = {}
25
+ scope[:request_store] = {}
16
26
  end
17
27
 
18
28
  def self.begin!
19
- Thread.current[:request_store_active] = true
29
+ scope[:request_store_active] = true
20
30
  end
21
31
 
22
32
  def self.end!
23
- Thread.current[:request_store_active] = false
33
+ scope[:request_store_active] = false
24
34
  end
25
35
 
26
36
  def self.active?
27
- Thread.current[:request_store_active] || false
37
+ scope[:request_store_active] || false
28
38
  end
29
39
 
30
40
  def self.read(key)
@@ -10,16 +10,15 @@ Gem::Specification.new do |gem|
10
10
  gem.email = ["steve@steveklabnik.com"]
11
11
  gem.description = %q{RequestStore gives you per-request global storage.}
12
12
  gem.summary = %q{RequestStore gives you per-request global storage.}
13
- gem.homepage = "http://github.com/steveklabnik/request_store"
13
+ gem.homepage = "https://github.com/steveklabnik/request_store"
14
14
  gem.licenses = ["MIT"]
15
15
 
16
16
  gem.files = `git ls-files`.split($/)
17
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
18
  gem.require_paths = ["lib"]
20
19
 
21
20
  gem.add_dependency "rack", ">= 1.4"
22
21
 
23
- gem.add_development_dependency "rake", "~> 10.5"
22
+ gem.add_development_dependency "rake"
24
23
  gem.add_development_dependency "minitest", "~> 5.0"
25
24
  end
@@ -12,6 +12,7 @@ class MiddlewareTest < Minitest::Test
12
12
  def call_middleware(opts = {})
13
13
  _, _, proxy = @middleware.call(opts)
14
14
  proxy.close
15
+ proxy
15
16
  end
16
17
 
17
18
  def test_middleware_resets_store
@@ -23,6 +24,17 @@ class MiddlewareTest < Minitest::Test
23
24
  assert_equal({}, RequestStore.store)
24
25
  end
25
26
 
27
+ def test_middleware_does_not_mutate_response_and_does_not_overflow_stack
28
+ 10000.times do
29
+ call_middleware
30
+ end
31
+
32
+ resp = call_middleware
33
+ assert resp.is_a?(::Rack::BodyProxy)
34
+ assert_equal ["response"], resp.to_a
35
+ assert_equal ["response"], resp.instance_variable_get(:@body)
36
+ end
37
+
26
38
  def test_middleware_resets_store_on_error
27
39
  e = assert_raises RuntimeError do
28
40
  call_middleware({:error => true})
@@ -63,3 +75,27 @@ class MiddlewareTest < Minitest::Test
63
75
  refute RequestStore.store[:foo]
64
76
  end
65
77
  end
78
+
79
+ class MiddlewareWithConstResponseTest < Minitest::Test
80
+ def setup
81
+ @app = RackAppWithConstResponse.new
82
+ @middleware = RequestStore::Middleware.new(@app)
83
+ end
84
+
85
+ def call_middleware(opts = {})
86
+ _, _, proxy = @middleware.call(opts)
87
+ proxy.close
88
+ proxy
89
+ end
90
+
91
+ def test_middleware_does_not_mutate_response_and_does_not_overflow_stack
92
+ 10000.times do
93
+ call_middleware
94
+ end
95
+
96
+ resp = call_middleware
97
+ assert resp.is_a?(::Rack::BodyProxy)
98
+ assert_equal ["response"], resp.to_a
99
+ assert_equal ["response"], resp.instance_variable_get(:@body)
100
+ end
101
+ end
@@ -63,9 +63,9 @@ class RequestStoreTest < Minitest::Test
63
63
  assert_equal 4, RequestStore.delete(:foo) { 2 + 2 }
64
64
  end
65
65
 
66
- def test_delegates_to_thread
66
+ def test_delegates_to_scope
67
67
  RequestStore.store[:foo] = 1
68
- assert_equal 1, Thread.current[:request_store][:foo]
68
+ assert_equal 1, RequestStore.scope[:request_store][:foo]
69
69
  end
70
70
 
71
71
  def test_active_state
data/test/test_helper.rb CHANGED
@@ -11,3 +11,19 @@ class RackApp
11
11
  [200, {}, ["response"]]
12
12
  end
13
13
  end
14
+
15
+ class RackAppWithConstResponse
16
+ RESPONSE = [200, {}, ["response"]]
17
+
18
+ attr_reader :last_value, :store_active
19
+
20
+ def call(env)
21
+ RequestStore.store[:foo] ||= 0
22
+ RequestStore.store[:foo] += 1
23
+ @last_value = RequestStore.store[:foo]
24
+ @store_active = RequestStore.active?
25
+ raise 'FAIL' if env[:error]
26
+
27
+ RESPONSE
28
+ end
29
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: request_store
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Klabnik
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-12-20 00:00:00.000000000 Z
11
+ date: 2024-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.5'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.5'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -59,8 +59,8 @@ executables: []
59
59
  extensions: []
60
60
  extra_rdoc_files: []
61
61
  files:
62
+ - ".github/workflows/ci.yml"
62
63
  - ".gitignore"
63
- - ".travis.yml"
64
64
  - Gemfile
65
65
  - LICENSE.txt
66
66
  - README.md
@@ -73,11 +73,11 @@ files:
73
73
  - test/middleware_test.rb
74
74
  - test/request_store_test.rb
75
75
  - test/test_helper.rb
76
- homepage: http://github.com/steveklabnik/request_store
76
+ homepage: https://github.com/steveklabnik/request_store
77
77
  licenses:
78
78
  - MIT
79
79
  metadata: {}
80
- post_install_message:
80
+ post_install_message:
81
81
  rdoc_options: []
82
82
  require_paths:
83
83
  - lib
@@ -92,8 +92,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0'
94
94
  requirements: []
95
- rubygems_version: 3.0.3
96
- signing_key:
95
+ rubygems_version: 3.2.15
96
+ signing_key:
97
97
  specification_version: 4
98
98
  summary: RequestStore gives you per-request global storage.
99
99
  test_files:
data/.travis.yml DELETED
@@ -1,18 +0,0 @@
1
- language: ruby
2
- sudo: false
3
- rvm:
4
- - 1.9.3
5
- - 2.0.0
6
- - 2.1.0
7
- - 2.2.3
8
- - 2.4.9
9
- - 2.5.7
10
- - 2.6.5
11
- - jruby-18mode
12
- - jruby-19mode
13
- - ruby-head
14
- - jruby-head
15
- matrix:
16
- allow_failures:
17
- - rvm: ruby-head
18
- - rvm: jruby-head