ruby 32 lines · 7 steps

A thread-safe throttle in Ruby

A Throttle class that rate-limits actions per key using a monotonic clock and a mutex for safe concurrent access.

Explained by highlit
1class Throttle
2 def initialize(interval)
3 @interval = interval
4 @mutex = Mutex.new
5 @last_called = {}
6 end
7 
8 def call(key = :default)
9 now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
10 
11 @mutex.synchronize do
12 last = @last_called[key]
13 return false if last && now - last < @interval
14 @last_called[key] = now
15 end
16 
17 yield
18 true
19 end
20 
21 def remaining(key = :default)
22 last = @mutex.synchronize { @last_called[key] }
23 return 0.0 unless last
24 
25 elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - last
26 [@interval - elapsed, 0.0].max
27 end
28 
29 def reset(key = :default)
30 @mutex.synchronize { @last_called.delete(key) }
31 end
32end
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1A monotonic clock avoids the bugs that wall-clock time introduces when the system clock jumps.
  2. 2Guarding shared state with a mutex keeps the check-and-update sequence atomic across threads.
  3. 3Keying timestamps by a value lets one throttle independently rate-limit many distinct actions.

Related explainers

Share this explainer

Here's the card — post it anywhere.

A thread-safe throttle in Ruby — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code