Skip to content

Commit

Permalink
fix: Correctly interpret x-request-start header when measured in nano…
Browse files Browse the repository at this point in the history
…seconds (#64)
  • Loading branch information
adamlogic committed Jan 26, 2023
1 parent 23c9059 commit 38276ce
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 5 deletions.
17 changes: 12 additions & 5 deletions judoscale-ruby/lib/judoscale/request_metrics.rb
Expand Up @@ -18,11 +18,18 @@ def ignore?

def started_at
if @request_start_header
# Heroku sets the header as an integer, measured in milliseconds.
# If nginx is involved, it might be in seconds with fractional milliseconds,
# and it might be preceeded by "t=". We can all cases by removing non-digits
# and treating as milliseconds.
Time.at(@request_start_header.gsub(/\D/, "").to_i / 1000.0)
# There are several variants of this header. We handle these:
# - whole milliseconds (Heroku)
# - whole nanoseconds (Render)
# - fractional seconds (NGINX)
# - preceeding "t=" (NGINX)
value = @request_start_header.gsub(/[^0-9.]/, "").to_f

case value
when 0..100_000_000_000 then Time.at(value)
when 100_000_000_000..100_000_000_000_000 then Time.at(value / 1000.0)
else Time.at(value / 1_000_000.0)
end
end
end

Expand Down
12 changes: 12 additions & 0 deletions judoscale-ruby/test/request_metrics_test.rb
Expand Up @@ -33,6 +33,18 @@ module Judoscale
end
end

it "handles X_REQUEST_START in nanoseconds" do
freeze_time do
started_at = Time.now.utc - 2
ended_at = started_at + 1
env["HTTP_X_REQUEST_START"] = (started_at.to_f * 1_000_000).to_i.to_s

# The queue time might return 999 or 1000 depending to time + float + format conversion,
# even when freezing time.
_(request.queue_time(ended_at)).must_be_within_delta 1000, 1
end
end

it "subtracts the network time / request body wait available in puma from the queue time" do
freeze_time do
started_at = Time.now.utc - 2
Expand Down

0 comments on commit 38276ce

Please sign in to comment.