{"id":50775655,"url":"https://github.com/drexed/timex","last_synced_at":"2026-06-11T23:02:52.848Z","repository":{"id":357935873,"uuid":"1239211793","full_name":"drexed/timex","owner":"drexed","description":"A Swiss-army knife for timeouts in Ruby.","archived":false,"fork":false,"pushed_at":"2026-05-14T21:52:57.000Z","size":1351,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-14T23:38:45.160Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/drexed.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-14T21:50:16.000Z","updated_at":"2026-05-14T21:52:26.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/drexed/timex","commit_stats":null,"previous_names":["drexed/timex"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/drexed/timex","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drexed%2Ftimex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drexed%2Ftimex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drexed%2Ftimex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drexed%2Ftimex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/drexed","download_url":"https://codeload.github.com/drexed/timex/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drexed%2Ftimex/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34221150,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-11T02:00:06.485Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-11T23:02:51.986Z","updated_at":"2026-06-11T23:02:52.839Z","avatar_url":"https://github.com/drexed.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"./src/timex-light-logo.png#gh-light-mode-only\" width=\"200\" alt=\"TIMEx Light Logo\"\u003e\n  \u003cimg src=\"./src/timex-dark-logo.png#gh-dark-mode-only\" width=\"200\" alt=\"TIMEx Dark Logo\"\u003e\n\n  ---\n\n  Deadlines, budgets, and cancellation you can reason about in production.\n\n  [Home](https://drexed.github.io/timex) ·\n  [Documentation](https://drexed.github.io/timex/getting_started) ·\n  [Blog](https://drexed.github.io/timex/blog) ·\n  [Changelog](./CHANGELOG.md) ·\n  [Report Bug](https://github.com/drexed/timex/issues) ·\n  [Request Feature](https://github.com/drexed/timex/issues) ·\n  [AI Skills](https://github.com/drexed/timex/blob/main/skills) ·\n  [llms.txt](https://drexed.github.io/timex/llms.txt) ·\n  [llms-full.txt](https://drexed.github.io/timex/llms-full.txt)\n\n  \u003cimg alt=\"Version\" src=\"https://img.shields.io/gem/v/timex\"\u003e\n  \u003cimg alt=\"Build\" src=\"https://github.com/drexed/timex/actions/workflows/ci.yml/badge.svg\"\u003e\n  \u003cimg alt=\"License\" src=\"https://img.shields.io/badge/license-LGPL%20v3-blue.svg\"\u003e\n\u003c/div\u003e\n\n# TIMEx\n\nTIMEx 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.\n\n\u003e [!NOTE]\n\u003e [Documentation](https://drexed.github.io/timex/getting_started/) reflects the latest code on `main`. For version-specific documentation, refer to the `docs/` directory within that version's tag.\n\n## What you get\n\n- **`TIMEx.deadline` / `TIMEx.call`** — single entrypoint with `strategy:`, `on_timeout:`, `auto_check:`, and strategy-specific options\n- **`Deadline`** — monotonic + wall alignment, narrowing (`#min`), skew-aware header encoding (`X-TIMEx-Deadline`)\n- **Strategies** — `:cooperative`, `:unsafe`, `:io`, `:wakeup`, `:subprocess`, `:closeable`, `:ractor` (when `Ractor` is defined), each registered on `TIMEx::Registry`\n- **Composers** — `TwoPhase`, `Hedged`, `Adaptive` for multi-attempt and staged execution\n- **`on_timeout`** — `:raise` (default), `:raise_standard`, `:return_nil`, `:result`, or a custom `Proc` with shared dispatch in `TimeoutHandling`\n- **`Result`** — discriminated `:ok` / `:timeout` / `:error` outcomes when you opt out of raising\n- **Propagation** — `Deadline#to_header` / `Deadline.from_header` plus optional Rack middleware for cross-service budgets\n- **Telemetry \u0026 clocks** — pluggable `Telemetry.adapter`, injectable monotonic/wall `Clock`, and `TIMEx::Test::VirtualClock` for tests\n- **Rails (opt-in)** — install generator adds initializer hooks without loading Rails from the core require\n\nSee the [feature comparison](https://drexed.github.io/timex/comparison/) for how TIMEx compares to `Timeout.timeout` and other patterns.\n\n## Requirements\n\n- Ruby: MRI 3.3+ or a compatible JRuby/TruffleRuby release\n- Runtime dependencies: none beyond the standard library (no ActiveSupport required)\n\nRails middleware and generators load only when you opt in after `bundle install`.\n\n## Installation\n\n```sh\ngem install timex\n# - or -\nbundle add timex\n```\n\n## Quick example\n\n### 1. Budget\n\nPass seconds, a `Deadline`, or `nil` for an infinite budget. The block receives a frozen `Deadline` you can thread through helpers.\n\n```ruby\ndeadline = TIMEx::Deadline.in(2.5)\nTIMEx.deadline(deadline) { |d| process!(d) }\n```\n\n### 2. Run\n\nThe default `:cooperative` strategy runs your block and performs a final `check!` so CPU-bound work still observes expiry at cooperative points.\n\n```ruby\nTIMEx.deadline(1.0) do |deadline|\n  rows = fetch_rows\n  deadline.check!\n  summarize(rows)\nend\n```\n\n### 3. On expiry\n\nOverride per call or via `TIMEx.configure`. Use `:result` when you want a `TIMEx::Result` instead of an exception.\n\n```ruby\noutcome = TIMEx.deadline(0.01, on_timeout: :result, strategy: :unsafe) do\n  sleep 5 # interrupted when the budget is exhausted\nend\n\noutcome.timeout? # =\u003e true\n```\n\n### 4. Propagate\n\nSerialize remaining budget into an outbound request so downstream services share the same cap.\n\n```ruby\nreq[\"X-TIMEx-Deadline\"] = TIMEx::Deadline.in(3.0).to_header\n# or use TIMEx::Propagation::RackMiddleware on the server (see docs)\n```\n\nReady to go deeper? Start with [Getting Started](https://drexed.github.io/timex/getting_started/) and [Migrating from stdlib `Timeout`](https://drexed.github.io/timex/migrating_from_stdlib_timeout/).\n\n## Contributing\n\nBug reports and pull requests are welcome at \u003chttps://github.com/drexed/timex\u003e. We're committed to fostering a welcoming, collaborative community. Please follow our [code of conduct](CODE_OF_CONDUCT.md).\n\n## License\n\nThe gem is available as open source under the terms of the [LGPLv3 License](https://www.gnu.org/licenses/lgpl-3.0.html).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrexed%2Ftimex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdrexed%2Ftimex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrexed%2Ftimex/lists"}