Skip to content

Commit 2c40745

Browse files
committed
Eagerly check for store validity
Ref: #315 `respond_to?` is a relatively expensive method that doesn't benefit from inline caching, so it has to keep looking up the method every time. Hence it's best to avoid it in hotspots. In this case, `@store` can only change through the `store=` method, so we might as well eagerly validate it there. First because this way it's a one time fixed cost, but also because this way the error is raised early during boot/configuration rather than at runtime where it has availability impact.
1 parent e938879 commit 2c40745

1 file changed

Lines changed: 10 additions & 12 deletions

File tree

lib/rack/attack/cache.rb

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ def store=(store)
2626
else
2727
store
2828
end
29+
if @store
30+
enforce_store_method_presence!(:read)
31+
enforce_store_method_presence!(:write)
32+
enforce_store_method_presence!(:delete)
33+
enforce_store_method_presence!(:increment)
34+
end
2935
end
3036

3137
def count(unprefixed_key, period)
@@ -34,13 +40,14 @@ def count(unprefixed_key, period)
3440
end
3541

3642
def read(unprefixed_key)
37-
enforce_store_presence!
38-
enforce_store_method_presence!(:read)
43+
raise Rack::Attack::MissingStoreError if store.nil?
3944

4045
store.read("#{prefix}:#{unprefixed_key}")
4146
end
4247

4348
def write(unprefixed_key, value, expires_in)
49+
raise Rack::Attack::MissingStoreError if store.nil?
50+
4451
store.write("#{prefix}:#{unprefixed_key}", value, expires_in: expires_in)
4552
end
4653

@@ -74,26 +81,17 @@ def key_and_expiry(unprefixed_key, period)
7481
end
7582

7683
def do_count(key, expires_in)
77-
enforce_store_presence!
78-
enforce_store_method_presence!(:increment)
84+
raise Rack::Attack::MissingStoreError if store.nil?
7985

8086
result = store.increment(key, 1, expires_in: expires_in)
8187

8288
# NB: Some stores return nil when incrementing uninitialized values
8389
if result.nil?
84-
enforce_store_method_presence!(:write)
85-
8690
store.write(key, 1, expires_in: expires_in)
8791
end
8892
result || 1
8993
end
9094

91-
def enforce_store_presence!
92-
if store.nil?
93-
raise Rack::Attack::MissingStoreError
94-
end
95-
end
96-
9795
def enforce_store_method_presence!(method_name)
9896
if !store.respond_to?(method_name)
9997
raise(

0 commit comments

Comments
 (0)