socketry/async
An awesome asynchronous event-driven reactor for Ruby.
Healthy across all four use cases
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 5w ago
- ✓4 active contributors
- ✓MIT licensed
Show 4 more →Show less
- ✓CI configured
- ✓Tests present
- ⚠Small team — 4 contributors active in recent commits
- ⚠Concentrated ownership — top contributor handles 78% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/socketry/async)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/socketry/async on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: socketry/async
Generated by RepoPilot · 2026-05-10 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/socketry/async shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- Last commit 5w ago
- 4 active contributors
- MIT licensed
- CI configured
- Tests present
- ⚠ Small team — 4 contributors active in recent commits
- ⚠ Concentrated ownership — top contributor handles 78% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live socketry/async
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/socketry/async.
What it runs against: a local clone of socketry/async — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in socketry/async | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | Last commit ≤ 65 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of socketry/async. If you don't
# have one yet, run these first:
#
# git clone https://github.com/socketry/async.git
# cd async
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of socketry/async and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "socketry/async(\\.git)?\\b" \\
&& ok "origin remote is socketry/async" \\
|| miss "origin remote is not socketry/async (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 65 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~35d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/socketry/async"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Async is a fiber-based asynchronous I/O reactor for Ruby built on io-event that enables thousands of concurrent connections per process without callbacks. It provides a lightweight, composable framework for event-driven programming using Ruby fibers, allowing developers to write non-blocking I/O code with synchronous-style syntax. Monorepo structure with lib/ containing the core reactor, task scheduler, and fiber-based concurrency primitives; benchmark/ includes performance tests for fibers, timers, barriers, and queues; .github/workflows/ orchestrates testing across multiple I/O backends (select, io-uring); context/ and assets/ provide documentation and branding.
👥Who it's for
Ruby backend developers and library maintainers building scalable web servers, real-time applications, or I/O-heavy services who need to handle thousands of concurrent connections without threading overhead or callback complexity. Contributors building the event-driven Ruby ecosystem around Async.
🌱Maturity & risk
Actively maintained and production-ready. The project shows consistent releases (v2.39.0 is recent), comprehensive CI/CD pipeline across multiple Ruby versions and event backends (test.yaml, test-select.yaml, test-uring.yaml workflows), extensive test coverage workflows, and a 300K+ line Ruby codebase. Maintenance is active with ongoing refinements (recent v2.38.0 API rename from stop→cancel, v2.37.0 added Async::Loop).
Low risk for a stable mature project. No visible single-maintainer dependency bottleneck (socketry org). Risks are minimal: the io-event C dependency could introduce platform-specific issues (hence multi-backend test workflows), but the abstraction is solid. Large codebase (304K lines) means complexity, but the modular design and extensive benchmarks (benchmark/ directory) suggest good architectural discipline.
Active areas of work
Recent development includes v2.39.0 (Barrier#wait returning task count), v2.38.1 (Barrier#async bug fix), v2.38.0 (Task#stop → Task#cancel rename with backward compatibility), and v2.37.0 (Async::Loop addition). Active CI testing across Ruby versions and I/O multiplexing backends (io-uring, select). Documentation workflows suggest ongoing investment in guides.
🚀Get running
git clone https://github.com/socketry/async.git
cd async
bundle install
bundle exec rake test
Daily commands:
No traditional dev server; Async is a library. For examples: look in benchmark/ directory for runnable demonstrations. Development: bundle exec rake test (inferred from test.yaml workflow). Documentation generation: bundle exec rake documentation (from documentation.yaml workflow).
🗺️Map of the codebase
- lib/async/scheduler.rb: Core event reactor loop managing fibers, timers, and I/O multiplexing; the heart of the framework
- lib/async/task.rb: Task abstraction wrapping fibers with lifecycle, waiting, and cancellation semantics
- lib/async/barrier.rb: Synchronization primitive for coordinating multiple concurrent tasks; frequently used pattern in async code
- .github/workflows/test.yaml: Main test CI pipeline; shows how to run tests and which Ruby/platform combinations are officially supported
- config/sus.rb: Test framework configuration; defines how tests are structured and executed
- benchmark/task.rb: Performance baseline for task creation and scheduling; important for understanding scalability claims
🛠️How to make changes
Core concurrency logic: lib/async/task.rb and lib/async/scheduler.rb. Add features to scheduler or task lifecycle. New I/O abstractions: lib/async/generic.rb and similar trait files. Benchmarks in benchmark/ for performance regression testing. Documentation in context/ guides. Tests follow sus.rb pattern; examine config/sus.rb for test structure.
🪤Traps & gotchas
- io-event is a native extension with platform-specific backends (io-uring, kqueue, epoll, select) — tests fail silently if C dependencies aren't installed. 2. Fibers don't yield automatically to the scheduler; you must use await-friendly I/O (use Async socket/HTTP libraries, not stdlib Socket directly). 3. Global state per Reactor — if you spawn multiple Async blocks without explicit task nesting, they may share the same scheduler (see v2.38.1 Barrier#async fix context). 4. Task#cancel (formerly Task#stop) is async cancellation; catching Async::Stop is required in long-running tasks.
💡Concepts to learn
- Fiber-based concurrency — Async's entire model is built on Ruby Fibers instead of OS threads, enabling thousands of concurrent tasks with minimal overhead; understanding fiber semantics (explicit yield points, no true parallelism) is critical to using Async correctly
🔗Related repos
socketry/io-event— Low-level C extension that Async depends on for platform-specific I/O multiplexing (epoll/kqueue/io-uring)socketry/async-http— HTTP client/server built on Async; the primary reference implementation for how to build async protocolssocketry/protocol-http2— HTTP/2 protocol implementation designed to work with Async for high-concurrency web servicesruby/fiber— Ruby's built-in Fiber class (stdlib) that Async wraps; understanding Fiber mechanics is essential to understanding Asyncruby/io-event— Companion to socketry/io-event; the ongoing effort to integrate event loop capabilities into Ruby stdlib
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive test coverage for benchmark suite baseline validation
The repo has extensive benchmarks (fiber-creation, thread-creation, queue, barrier, task timing, etc.) but no CI workflow to track performance regressions. Adding a test-benchmarks.yaml workflow would help catch performance degradations early. This is critical for an async I/O framework where performance is a key selling point.
- [ ] Create .github/workflows/test-benchmarks.yaml to run benchmark/core/fiber-creation.rb and benchmark/core/thread-creation.rb
- [ ] Store baseline results from benchmark/core/results.md as a reference point
- [ ] Add step to compare current run against baseline and warn if performance degrades >5%
- [ ] Document benchmark setup in context/scheduler.md or new benchmarking guide
Add missing context documentation for common debugging patterns
The repo has context/debugging.md listed but examining the file structure suggests it may be incomplete. Given the async nature of this framework, contributors need specific guidance on debugging concurrency issues, fiber state inspection, and trace analysis. The config/traces.rb hints at tracing capabilities that should be documented.
- [ ] Expand context/debugging.md with concrete examples of using config/traces.rb for tracing async tasks
- [ ] Add section on inspecting fiber state and common deadlock scenarios
- [ ] Document how to use the examples/bugs/write_lock.rb pattern to identify thread-safety issues
- [ ] Link to the test-agent-context.yaml workflow as an example of testing complex async scenarios
Create integration test suite for dataloader example with real-world backends
The examples/dataloader example exists but there's no dedicated test workflow validating it works correctly. This is a critical integration pattern that many users will adopt. Adding a test workflow ensures the example stays functional across Ruby/dependency updates and serves as executable documentation.
- [ ] Create examples/dataloader/spec directory with integration tests
- [ ] Add test cases for batch operations, error handling, and concurrency limits
- [ ] Create .github/workflows/test-dataloader.yaml to run the integration tests
- [ ] Verify example works with the gems.locked dependencies defined in examples/dataloader/gems.locked
🌿Good first issues
- Add micro-benchmarks for Async::Condition and Async::Queue in benchmark/ (currently has barrier.rb and queue.rb but no condition.rb counterpart) to establish performance baselines
- Expand context/getting-started.md with a worked example showing fiber-safe HTTP client code (calling async web APIs) vs naive stdlib approach to highlight the problem Async solves
- Add integration tests under a new spec/ or test/ directory validating the interaction between Barrier, Condition, and Queue primitives under contention (currently benchmarks exist but no regression test suite)
⭐Top contributors
Click to expand
Top contributors
- @ioquatix — 78 commits
- @samuel-williams-shopify — 20 commits
- @tavianator — 1 commits
- @Yuhi-Sato — 1 commits
📝Recent commits
Click to expand
Recent commits
886d62c— Bump minor version. (ioquatix)2c89c3f— Make the test more robust. (ioquatix)751b6aa— Barrier waits return nil or number of tasks waited on. (ioquatix)7f00f35— Break the cycle between the task and the fiber as early as possible. (ioquatix)975b9fa— Bump patch version. (ioquatix)6e31c55— Update copyrights. (ioquatix)dfe96b4— Add support for automatic GitHub release notes. (ioquatix)1d91f85— Fix Barrier when parent.async() yields early (#449) (tavianator)9182cde— Bump minor version. (ioquatix)3318a3e— Update release notes. (ioquatix)
🔒Security observations
The socketry/async codebase shows a well-organized structure with clear separation of concerns. No obvious hardcoded secrets or credentials were detected in file names or visible structure. However, critical information is missing: the actual dependency file content prevents assessment of vulnerable dependencies, and configuration files are not visible for review. The project includes CI/CD workflows for testing and rubocop linting, which is positive. Main recommendations: (1) Provide full dependency manifests for vulnerability scanning, (2) Review and audit all configuration files, (3) Ensure no credentials are stored in version control, (4) Continue leveraging automated security scanning in CI/CD pipelines.
- Low · Benchmark Dependencies Not Pinned —
benchmark/timers/gems.rb, benchmark/gems.rb. The benchmark directory contains gems.rb and gems.locked files, but without visibility into the actual dependency versions, there's a potential risk of using outdated or vulnerable gems during performance testing. The 'gems.locked' file suggests pinned dependencies, but the process for updating them is unclear. Fix: Ensure all benchmark dependencies are regularly updated and audited. Usebundler auditor similar tools to scan for known vulnerabilities in locked dependencies. - Low · Missing Dependency File Content —
Root gemspec and Gemfile (not provided). The 'Dependencies/Package file content' section is empty, making it impossible to perform a comprehensive security audit of the project's direct and transitive dependencies. This is critical for identifying vulnerable dependencies. Fix: Provide the full content of async.gemspec and Gemfile (if present) to enable dependency vulnerability scanning. Integrate automated dependency scanning tools into CI/CD pipelines (e.g., Dependabot, Snyk). - Medium · Configuration Files Lack Security Review Indicators —
config/ directory. The codebase contains several configuration files (config/environment.yaml, config/external.yaml, config/metrics.rb, config/traces.rb) without visibility into their content. These could potentially contain sensitive configuration, hardcoded credentials, or insecure defaults. Fix: Review all configuration files to ensure: 1) No hardcoded credentials, API keys, or secrets, 2) Secure defaults for all security-related settings, 3) Sensitive data uses environment variables, 4) Add config files to .gitignore if they contain secrets. - Low · Example Code May Contain Non-Production Patterns —
examples/ directory. The examples/ directory contains various demonstration scripts and code samples. While these are intended for educational purposes, they may contain insecure patterns (e.g., examples/bugs/write_lock.rb) that could mislead users about best practices. Fix: Ensure all examples are clearly marked with their intended purpose. Add security warnings to examples that demonstrate problematic patterns. Document best practices prominently in the README and guides.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.