ruby
31 lines · 6 steps
Bounding a slow HTTP call with Timeout in Ruby
A remote inventory client caps its upstream request and falls back to a stale cache when the deadline is blown.
Explained by
highlit
1require "timeout"
2require "net/http"
3
4class RemoteInventoryClient
5 class SlowUpstreamError < StandardError; end
6
7 DEFAULT_TIMEOUT = 3.0
8
9 def initialize(base_uri, timeout: DEFAULT_TIMEOUT)
10 @base_uri = URI(base_uri)
11 @timeout = timeout
12 end
13
14 def stock_level(sku)
15 Timeout.timeout(@timeout, SlowUpstreamError, "inventory lookup exceeded #{@timeout}s") do
16 response = fetch("/skus/#{sku}/stock")
17 JSON.parse(response.body).fetch("available")
18 end
19 rescue SlowUpstreamError => e
20 Rails.logger.warn("[inventory] #{e.message} sku=#{sku}")
21 StaleStockCache.fetch(sku)
22 end
23
24 private
25
26 def fetch(path)
27 Net::HTTP.start(@base_uri.host, @base_uri.port, use_ssl: @base_uri.scheme == "https") do |http|
28 http.request(Net::HTTP::Get.new(path))
29 end
30 end
31end
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Wrapping risky I/O in Timeout.timeout with a custom exception makes deadline failures easy to catch and handle distinctly.
- 2Pairing a hard timeout with a stale-cache fallback keeps a service responsive even when an upstream degrades.
- 3Configurable timeouts with a sensible default let callers tune latency budgets without touching call sites.
Related explainers
ruby
class ToastBroadcaster include ActionView::RecordIdentifier def self.broadcast_to(user, message:, type: :notice)
How Turbo Stream toasts broadcast in Rails
turbo-streams
service-object
real-time
Intermediate
6 steps
ruby
class TemplateInterpolator PLACEHOLDER = /\{\{\s*([\w.]+)\s*\}\}/ def initialize(strict: false)
Interpolating templates with dotted keys in Ruby
regex
string-interpolation
hash-traversal
Intermediate
6 steps
ruby
class KeyTransformer def self.camelize(data) new.camelize(data) end
Recursively camelizing nested Ruby data
recursion
data-transformation
pattern-matching
Intermediate
7 steps
ruby
module Paginatable extend ActiveSupport::Concern private
A reusable pagination concern in Rails
pagination
concerns
http-headers
Intermediate
8 steps
go
package config import ( "fmt"
A thread-safe config singleton in Go
singleton
concurrency
environment-variables
Intermediate
7 steps
rust
use std::net::Ipv4Addr; use std::str::FromStr; #[derive(Debug, Clone, Copy)]
Parsing and matching IPv4 CIDR ranges in Rust
bitwise-operations
parsing
error-handling
Intermediate
8 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/bounding-a-slow-http-call-with-timeout-in-ruby-explained-ruby-819c/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.