Project

timex

0.0
No release in over 3 years
A Swiss-army knife for timeouts in Ruby.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies
 Project Readme
TIMEx Light Logo TIMEx Dark Logo

Deadlines, budgets, and cancellation you can reason about in production.

Home · Documentation · Blog · Changelog · Report Bug · Request Feature · AI Skills · llms.txt · llms-full.txt

Version Build License

TIMEx

TIMEx is a deadline engine for Ruby: one facade runs your code under a Deadline, picks an execution strategy (cooperative checks, thread wakeup, IO deadlines, subprocesses, and more), and routes expiry through consistent on_timeout semantics—without pulling in a framework.

Note

Documentation reflects the latest code on main. For version-specific documentation, refer to the docs/ directory within that version's tag.

What you get

  • TIMEx.deadline / TIMEx.call — single entrypoint with strategy:, on_timeout:, auto_check:, and strategy-specific options
  • Deadline — monotonic + wall alignment, narrowing (#min), skew-aware header encoding (X-TIMEx-Deadline)
  • Strategies:cooperative, :unsafe, :io, :wakeup, :subprocess, :closeable, :ractor (when Ractor is defined), each registered on TIMEx::Registry
  • ComposersTwoPhase, Hedged, Adaptive for multi-attempt and staged execution
  • on_timeout:raise (default), :raise_standard, :return_nil, :result, or a custom Proc with shared dispatch in TimeoutHandling
  • Result — discriminated :ok / :timeout / :error outcomes when you opt out of raising
  • PropagationDeadline#to_header / Deadline.from_header plus optional Rack middleware for cross-service budgets
  • Telemetry & clocks — pluggable Telemetry.adapter, injectable monotonic/wall Clock, and TIMEx::Test::VirtualClock for tests
  • Rails (opt-in) — install generator adds initializer hooks without loading Rails from the core require

See the feature comparison for how TIMEx compares to Timeout.timeout and other patterns.

Requirements

  • Ruby: MRI 3.3+ or a compatible JRuby/TruffleRuby release
  • Runtime dependencies: none beyond the standard library (no ActiveSupport required)

Rails middleware and generators load only when you opt in after bundle install.

Installation

gem install timex
# - or -
bundle add timex

Quick example

1. Budget

Pass seconds, a Deadline, or nil for an infinite budget. The block receives a frozen Deadline you can thread through helpers.

deadline = TIMEx::Deadline.in(2.5)
TIMEx.deadline(deadline) { |d| process!(d) }

2. Run

The default :cooperative strategy runs your block and performs a final check! so CPU-bound work still observes expiry at cooperative points.

TIMEx.deadline(1.0) do |deadline|
  rows = fetch_rows
  deadline.check!
  summarize(rows)
end

3. On expiry

Override per call or via TIMEx.configure. Use :result when you want a TIMEx::Result instead of an exception.

outcome = TIMEx.deadline(0.01, on_timeout: :result, strategy: :unsafe) do
  sleep 5 # interrupted when the budget is exhausted
end

outcome.timeout? # => true

4. Propagate

Serialize remaining budget into an outbound request so downstream services share the same cap.

req["X-TIMEx-Deadline"] = TIMEx::Deadline.in(3.0).to_header
# or use TIMEx::Propagation::RackMiddleware on the server (see docs)

Ready to go deeper? Start with Getting Started and Migrating from stdlib Timeout.

Contributing

Bug reports and pull requests are welcome at https://github.com/drexed/timex. We're committed to fostering a welcoming, collaborative community. Please follow our code of conduct.

License

The gem is available as open source under the terms of the LGPLv3 License.