# Async::Safe

Runtime thread safety monitoring for concurrent Ruby code.

This gem provides a TracePoint-based ownership tracking system that detects when objects are accessed from multiple fibers or threads without proper synchronization. It helps catch concurrency bugs during development and testing with zero overhead in production.

[![Development Status](https://github.com/socketry/async-safe/workflows/Test/badge.svg)](https://github.com/socketry/async-safe/actions?workflow=Test)

## Motivation

Ruby's fiber-based concurrency (via `async`) can lead to data races when objects are accessed concurrently. This gem helps you catch these concurrency bugs in your test suite by detecting when multiple fibers access the same object simultaneously.

Enable it in your tests to get immediate feedback when invalid concurrent access occurs.

## Usage

Please see the [project documentation](https://socketry.github.io/async-safe/) for more details.

  - [Getting Started](https://socketry.github.io/async-safe/guides/getting-started/index) - This guide explains how to use `async-safe` to detect thread safety violations in your Ruby code.

## Releases

Please see the [project releases](https://socketry.github.io/async-safe/releases/index) for all releases.

### v0.5.1

  - Protect against missing guard in `check_return`.
  - Use `Kernel` instance methods to handle broken proxy objects directly.

### v0.5.0

  - More conservative tracking of objects using call/return for ownership transfer.
  - Introduced guard concept for splitting ownership within a single object, e.g. independently concurrent readable and writable parts of an object.

### v0.4.0

  - Improved `Async::Safe.transfer` to recursively transfer ownership of tracked instance variables.

### v0.3.2

  - Better error message.

### v0.3.0

  - Inverted default model: classes are async-safe by default, use `ASYNC_SAFE = false` to enable tracking.
  - Added flexible `ASYNC_SAFE` constant support: boolean, hash, or array configurations.
  - Added `Class#async_safe!` method for marking classes.
  - Added `Class#async_safe?(method)` method for querying safety.
  - Added `Class.async_safe_traverse` for custom deep transfer traversal (opt-in).
  - Improved `Async::Safe.transfer` to use shallow transfer by default with opt-in deep traversal.
  - Mark built-in collections (`Array`, `Hash`, `Set`) as single-owner with deep traversal support.
  - Removed logger feature: always raises `ViolationError` exceptions.
  - Removed `Async::Safe::Concurrent` module: use `async_safe!` instead.

### v0.2.0

  - `Thread::Queue` transfers ownership of objects popped from it.
  - Add support for `logger:` option in `Async::Safe.enable!` which logs violations instead of raising errors.

### v0.1.0

  - Implement TracePoint-based ownership tracking.
  - Add `Async::Safe::Concurrent` module for marking thread-safe classes.
  - Add `thread_safe` class method for marking thread-safe methods.
  - Add `Async::Safe.transfer` for explicit ownership transfer
  - Add violation detection and reporting
  - Zero overhead when monitoring is disabled

## See Also

  - [async](https://github.com/socketry/async) - Composable asynchronous I/O for Ruby.
  - [Thread Safety Guide](https://github.com/socketry/async/blob/main/.context/async/thread-safety.md) - Best practices for concurrent Ruby code.

## Contributing

We welcome contributions to this project.

1.  Fork it.
2.  Create your feature branch (`git checkout -b my-new-feature`).
3.  Commit your changes (`git commit -am 'Add some feature'`).
4.  Push to the branch (`git push origin my-new-feature`).
5.  Create new Pull Request.

### Developer Certificate of Origin

In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.

### Community Guidelines

This project is best served by a collaborative and respectful environment. Treat each other professionally, respect differing viewpoints, and engage constructively. Harassment, discrimination, or harmful behavior is not tolerated. Communicate clearly, listen actively, and support one another. If any issues arise, please inform the project maintainers.
