Skip to content

Commit 4c4f4c3

Browse files
Avoid double JSON parse for metadata-less messages
In rails#46612, a check was added to only attempt metadata extraction if the message looks like a JSON object (i.e. starts with "{"), thus avoiding an unnecessary JSON parse and possible exception. This commit extends the check to only attempt metadata extraction if the message looks like a metadata wrapper object (i.e. has the "_rails" key). This avoids an unnecessary JSON parse of JSON object messages that don't have metadata. **Benchmark** ```ruby require "benchmark/ips" require "active_support/all" verifier = ActiveSupport::MessageVerifier.new("secret", serializer: JSON) message_100 = verifier.generate({ content: "x" * 100 }) message_1m = verifier.generate({ content: "x" * 1_000_000 }) Benchmark.ips do |x| x.report("100 chars") do verifier.verify(message_100) end x.report("1m chars") do verifier.verify(message_1m) end end ``` **Before** ``` Warming up -------------------------------------- 100 chars 2.803k i/100ms 1m chars 6.000 i/100ms Calculating ------------------------------------- 100 chars 27.762k (± 1.6%) i/s - 140.150k in 5.049649s 1m chars 83.516 (±16.8%) i/s - 402.000 in 5.037269s ``` **After** ``` Warming up -------------------------------------- 100 chars 3.360k i/100ms 1m chars 9.000 i/100ms Calculating ------------------------------------- 100 chars 33.480k (± 1.7%) i/s - 168.000k in 5.019311s 1m chars 113.373 (±15.0%) i/s - 549.000 in 5.023443s ```
1 parent 52146de commit 4c4f4c3

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

activesupport/lib/active_support/messages/metadata.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@ def pick_expiry(expires_at, expires_in)
3838

3939
def extract_metadata(message)
4040
begin
41-
data = JSON.decode(message) if message.start_with?("{")
41+
data = JSON.decode(message) if message.start_with?('{"_rails":')
4242
rescue ::JSON::JSONError
4343
end
4444

45-
if data.is_a?(Hash) && data.key?("_rails")
45+
if data
4646
new(decode(data["_rails"]["message"]), data["_rails"]["exp"], data["_rails"]["pur"])
4747
else
4848
new(message)

0 commit comments

Comments
 (0)