• Stars
    star
    1,415
  • Rank 31,958 (Top 0.7 %)
  • Language
    Ruby
  • License
    MIT License
  • Created over 11 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Per-request global storage for Rack.

RequestStore CI Code Climate

Ever needed to use a global variable in Rails? Ugh, that's the worst. If you need global state, you've probably reached for Thread.current. Like this:

def self.foo
  Thread.current[:foo] ||= 0
end

def self.foo=(value)
  Thread.current[:foo] = value
end

Ugh! I hate it. But you gotta do what you gotta do...

The problem

Everyone's worrying about concurrency these days. So people are using those fancy threaded web servers, like Thin or Puma. But if you use Thread.current, and you use one of those servers, watch out! Values can stick around longer than you'd expect, and this can cause bugs. For example, if we had this in our controller:

def index
  Thread.current[:counter] ||= 0
  Thread.current[:counter] += 1

  render :text => Thread.current[:counter]
end

If we ran this on MRI with Webrick, you'd get 1 as output, every time. But if you run it with Thin, you get 1, then 2, then 3...

The solution

Add this line to your application's Gemfile:

gem 'request_store'

And change the code to this:

def index
  RequestStore.store[:foo] ||= 0
  RequestStore.store[:foo] += 1

  render :text => RequestStore.store[:foo]
end

Yep, everywhere you used Thread.current just change it to RequestStore.store. Now no matter what server you use, you'll get 1 every time: the storage is local to that request.

API

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.

top_posts = RequestStore.fetch(:top_posts) do
  # code to obtain the top posts
end

Rails 2 compatibility

The gem includes a Railtie that will configure everything properly for Rails 3+ apps, but if your app is tied to an older (2.x) version, you will have to manually add the middleware yourself. Typically this should just be a matter of adding:

config.middleware.use RequestStore::Middleware

into your config/environment.rb.

No Rails? No Problem!

A Railtie is added that configures the Middleware for you, but if you're not using Rails, no biggie! Just use the Middleware yourself, however you need. You'll probably have to shove this somewhere:

use RequestStore::Middleware

No Rails + Rack::Test

In order to have RequestStore storage cleared between requests, add it to the app:

# spec_helper.rb

def app
  Rack::Builder.new do
    use RequestStore::Middleware
    run MyApp
  end
end

Using with Sidekiq

This gem uses a Rack middleware to clear the store object after every request, but that doesn't translate well to background processing with Sidekiq.

A companion library, request_store-sidekiq creates a Sidekiq middleware that will ensure the store is cleared after each job is processed, for security and consistency with how this is done in Rack.

Semantic Versioning

This project conforms to semver. As a result of this policy, you can (and should) specify a dependency on this gem using the Pessimistic Version Constraint with two digits of precision. For example:

spec.add_dependency 'request_store', '~> 1.0'

This means your project is compatible with request_store 1.0 up until 2.0. You can also set a higher minimum version:

spec.add_dependency 'request_store', '~> 1.1'

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Don't forget to run the tests with rake.

More Repositories

1

CLOSURE

Thanks, _why.
502
star
2

rust_for_rubyists

Learn Rust
HTML
426
star
3

frappuccino

Functional Reactive Programming in Ruby.
Ruby
354
star
4

automatically_update_github_pages_with_travis_example

An example of automatically updating GitHub Pages when you're using Travis CI.
Shell
240
star
5

simple-server

A simple webserver built on top of the Rust standard library and the http crate.
Rust
177
star
6

doxidize

Amazing documentation tooling for Rust
Rust
152
star
7

rustbook

A simplified version of gitbook, atop rustdoc
Rust
123
star
8

mono_logger

A lock-free logger for Ruby 2.0
Ruby
107
star
9

rustdoc

Not a real thing, see https://github.com/rust-lang/rust for rustdoc's actual source code
103
star
10

words

A way to turn markdown into HTML and ebooks
102
star
11

rust_example

A Ruby gem, implemented in Rust
Ruby
101
star
12

indexlist

indexlist: A doubly linked list, backed by a vector
Rust
82
star
13

rust-in-ten-slides

Short presentations about Rust syntax + concepts
HTML
72
star
14

turbolinks_test

Seriously. Use numbers.
Ruby
71
star
15

rustmvc

TodoMVC, with Rust and Ember
JavaScript
70
star
16

mojikun

A programming language that you'll ❤️
Ruby
70
star
17

metadown

Annotate your Markdown files with metadata.
Ruby
69
star
18

ruby-sys

Low-level bindings to Ruby
Rust
65
star
19

becoming

Add additional functionality to objects.
Ruby
42
star
20

pomodoro

A pomodoro counter, that turns off your access to certain sites.
Ruby
42
star
21

issue2pr

Transmute your Issues into Pull Requests
CSS
39
star
22

ticketee_review

The example application for Rails 4 in Action.
Ruby
38
star
23

sunlight-congress

A wrapper for the Sunlight Foundation's Congress API
Ruby
36
star
24

history-of-rust

A talk about the history of Rust
HTML
35
star
25

security_release_practice

Ruby
34
star
26

semver-parser

A parser for the semver specification
Rust
33
star
27

blog

This is my blog.
CSS
32
star
28

ticketee

The sample app for Rails 4 in Action
Ruby
32
star
29

dining_philosophers

The Dining Philosophers problem, in Rust
Rust
28
star
30

ref_slice

Take a reference and get back a slice of length one
Rust
26
star
31

hateoas

Build easy clients for Hypermedia APIs.
Ruby
25
star
32

adventure

A text adventure game, in Rust.
Rust
24
star
33

derp

Lets you herp all of your Strings with a to_derp method.
Ruby
21
star
34

trpl

don't worry about it
20
star
35

get_a_job

A hypermedia job queue
Ruby
20
star
36

bring_back_snowman

Ruby
20
star
37

buck-rust-hello

A demo of using buck2 with Rust.
Starlark
19
star
38

json-merge_patch

An implementation of the snell-merge-patch draft for JSON.
Ruby
18
star
39

ticketee_backup

A ticking application. The example app for "Rails 4 in Action"
Ruby
17
star
40

livestream

the source of the stuff I do on twitch.tv
Rust
16
star
41

how_i_start

A sample project for How I Start.
Ruby
16
star
42

jujutsu-tutorial

trying to figure out this jujutsu thing
16
star
43

no_secrets_anymore

JavaScript
15
star
44

pastebin

This is a copy of the old pastebin 6.0 code
PHP
15
star
45

teachmehowtomakearubygem

Shows you how to make a ruby gem.
Ruby
15
star
46

warehouse

Crates.io's index as a web app.
JavaScript
14
star
47

ludum

My entry for Ludum Dare 35
Rust
13
star
48

forward2015

My talk from forward2015
HTML
13
star
49

abnf

A ABNF parser for Ruby.
Ruby
13
star
50

dtp

Document Transfer Protocol
12
star
51

media_type_template

A template for media type definitions
JavaScript
11
star
52

rwc

A wc clone in Rust
Rust
10
star
53

hypermedia-presentation

JavaScript
10
star
54

require_relative

This backports require_relative to Ruby 1.8.
Ruby
10
star
55

from_behind

Rogues do it from behind; a roguelike in Haskell
Haskell
9
star
56

eployday

A deploy bot for IRC
Ruby
9
star
57

frp_shoes

Functional Reactive Programming + Shoes
Ruby
8
star
58

open_company_talk

A talk about open companies.
JavaScript
8
star
59

grok

Fun with compilers, interpreters and such.
Rust
8
star
60

password-cracker

ceasar cypher cracker in rust
Rust
7
star
61

oredev2018

My talk at Oredev 2018: rustc errors a UX perspective
JavaScript
6
star
62

uniq_ptr_problem

Unsafety with uniq_ptr in C++
HTML
6
star
63

maze_solver

Some experiments with Maze+XML
Ruby
6
star
64

meloria

CRM for tattoo shops
Ruby
5
star
65

not-the-rust-blog

CSS
5
star
66

the_rust_programming_language

Makefile
5
star
67

parse-example

Parsing a file to a struct in Rust
Rust
5
star
68

antisocialne.ws

fuck reddit
Ruby
5
star
69

heroku-buildpack-rbx

Shell
5
star
70

extraextra

Need to add a news feed to your application? EXTRA! EXTRA! is just the Gem for you!
Ruby
5
star
71

rustconf2018-wasm-workshop

The WebAssembly workshop at RustConf 2018
HTML
5
star
72

nobody_knows_rust

JavaScript
5
star
73

bad_idea

this is a bad idea
Makefile
5
star
74

rust-algebra

Monoids, semigroups, and other algebraic structures in Rust
Rust
5
star
75

nasm-rust

Rust
4
star
76

guessing_game

The classic guessing game in Rust.
Rust
4
star
77

rust-adt

A collection of abstract data types, written in Rust
Rust
4
star
78

compass-rust

Rust
4
star
79

cryptopals

http://cryptopals.com/ in Rust
Rust
4
star
80

fosdem2015

My slides for FOSDEM 2015
JavaScript
4
star
81

totally-not-semver

Rust
4
star
82

aoc2017

Advent of Code 2017
HTML
4
star
83

s

My own personal sub: https://github.com/37signals/sub
Shell
4
star
84

rust-linked-lists

Several linked list implementations in Rust
Rust
4
star
85

steveklabnik.com

My personal website.
MDX
4
star
86

geekout2016

The code from my talk at GeekOut
Rust
4
star
87

ActiveRepository

A brain dump of a new persistence strategy for Rails.
Ruby
4
star
88

art_of_ruby

JavaScript
4
star
89

avr-emulator

Atmel 8-bit AVR Emulator in React and Rust
Rust
3
star
90

coinbaser

Coinbase REST API for Rust
Rust
3
star
91

bitcoin-secp256k1-rs

Rust language bindings for Bitcoin secp256k1 library.
Rust
3
star
92

learn_c_the_hard_way_exercises

3
star
93

rust_documentation

A talk about Rust's docs.
JavaScript
3
star
94

heroku-buildpack-rust-wasm

Shell
3
star
95

attendr

Ruby
3
star
96

booster2018

Our workshop at BoosterConf 2018
HTML
3
star
97

semver.crates.io

Rust
3
star
98

daw

A little DAW, in Shoes
Ruby
3
star
99

webscale-ruby-version

This makes RUBY_VERSION web scale
Ruby
2
star
100

workers-steveklabnik.com

My personal website
HTML
2
star