ractor-wrapper 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -0
- data/CLAUDE.md +76 -0
- data/LICENSE.md +1 -1
- data/README.md +423 -88
- data/lib/ractor/wrapper/version.rb +3 -1
- data/lib/ractor/wrapper.rb +1071 -442
- data/lib/ractor-wrapper.rb +2 -0
- metadata +9 -12
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b3948e5f98b34503dc8e6075eb8a186ae1c76a53f0f45164396bb006ad802964
|
|
4
|
+
data.tar.gz: 58eaa1ac8d9d0088b1f8df5e45d746a084a921eef53eb96563c0700eb9144dde
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3b31f168446571aad39874d04542818ccea56bb3165e2a081fb5135f72b0498c2e73eb5fec4431cd712f8326ced6c6924a3600833895e356fb7cb154ac6f2023
|
|
7
|
+
data.tar.gz: 9d679b50a36ee4303117d46bd404f649ca1a71f724c8dbe6ba13ba28f77228e1071839d7b06d8c965cb7946e411178b86bcfb08b77c0bfdc2e0c2420121ede1a
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# Release History
|
|
2
2
|
|
|
3
|
+
### v0.4.0 / 2026-03-30
|
|
4
|
+
|
|
5
|
+
This release includes two major changes: it greatly improves robustness in the case of server crashes, and it reworks the method call configuration interface. This involves several breaking changes, and I expect the interface will continue to be a bit unstable for now as I'm working through use cases and edge cases. The README has also been expanded to include more information on the configuration options and the known issues.
|
|
6
|
+
|
|
7
|
+
* ADDED: Uses a separate `Ractor::Wrapper::Configuration` class for block-based initialization. Removed the configuration mutation methods from `Ractor::Wrapper` itself.
|
|
8
|
+
* BREAKING CHANGE: The method configuration interface now uses symbolic settings values instead of booleans for more flexibility
|
|
9
|
+
* ADDED: Support for suppressing return values for methods and blocks that unintentionally return something they shouldn't
|
|
10
|
+
* BREAKING CHANGE: Raises `Ractor::Wrapper::StoppedError` instead of `Ractor::ClosedError` if a method is called via the wrapper after the wrapper has stopped
|
|
11
|
+
* BREAKING CHANGE: `Wrapper#join` now returns normally rather than raising, if an isolated wrapper terminated due to a crash
|
|
12
|
+
* BREAKING FIX: `Wrapper#join` no longer hangs if a local wrapper crashes, but returns to indicate that the wrapper has stopped (albeit non-normally)
|
|
13
|
+
* FIXED: Internal cleanup is more robust if a crash occurs in the wrapper
|
|
14
|
+
* FIXED: Method calls raise `Ractor::Wrapper::CrashedError` instead of hanging if the wrapper crashes during handling
|
|
15
|
+
* FIXED: Prevented port leaks if a method call send or a block yield send fails
|
|
16
|
+
* FIXED: Methods that return or yield self return/yield the stub instead
|
|
17
|
+
* FIXED: The `recover_object` method now raises `Ractor::Wrapper::Error` if recovery failed
|
|
18
|
+
* DOCS: Updates to README
|
|
19
|
+
|
|
20
|
+
### v0.3.0 / 2026-01-05
|
|
21
|
+
|
|
22
|
+
This is a major update, and the library, while still experimental, is finally somewhat usable. The examples in the README now actually work!
|
|
23
|
+
|
|
24
|
+
Earlier versions were severely hampered by limitations of the Ractor implementation in Ruby 3. Many of these were fixed in Ruby 4.0, and Ractor::Wrapper has been updated to take advantage of it. This new version requires Ruby 4.0.0 or later, and includes a number of enhancements:
|
|
25
|
+
|
|
26
|
+
* Support for running a wrapper in the current Ractor, useful for wrapping objects that cannot be moved, or that must run in the main Ractor. (By default, wrapped objects are still moved into an isolated Ractor to maximize cleanliness and concurrency.)
|
|
27
|
+
* Support for running a wrapper sequentially without worker threads. This is now the default behavior, which does not spawn any extra threads in the wrapper. (Earlier behavior would spawn exactly one worker thread by default.)
|
|
28
|
+
* Limited support for passing blocks to a wrapped object. You can cause a block to run "in place" within the wrapper, as long as the block can be made shareable (i.e. does not access any outside data), or have the block run in the caller's context with the cost of some additional communication. You can also configure that communication to move or copy data.
|
|
29
|
+
* Provided Ractor::Wrapper#join for waiting for a wrapper to complete without asking for the wrapped object back.
|
|
30
|
+
* Some of the configuration parameters have been renamed.
|
|
31
|
+
|
|
32
|
+
Some caveats remain, so please consult the README for details. This library should still be considered experimental, and not suitable for production use. I reserve the right to make breaking changes at any time.
|
|
33
|
+
|
|
3
34
|
### v0.2.0 / 2021-03-08
|
|
4
35
|
|
|
5
36
|
* BREAKING CHANGE: The wrapper now copies (instead of moves) arguments and return values by default.
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
This project uses [Toys](https://dazuma.github.io/toys) for task management (not Rake).
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Run full CI pipeline
|
|
11
|
+
toys ci
|
|
12
|
+
|
|
13
|
+
# Run individual components
|
|
14
|
+
toys test # Tests only
|
|
15
|
+
toys rubocop # Linting and code style only
|
|
16
|
+
toys yardoc # Documentation only
|
|
17
|
+
toys build # Build gem only
|
|
18
|
+
|
|
19
|
+
# Run a single test file
|
|
20
|
+
toys test test/test_wrapper.rb
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Architecture
|
|
24
|
+
|
|
25
|
+
The entire library lives in `lib/ractor/wrapper.rb`. The public entry point is `Ractor::Wrapper`, which wraps a non-shareable object and exposes it to other Ractors via a shareable `Stub` proxy.
|
|
26
|
+
|
|
27
|
+
### Core classes
|
|
28
|
+
|
|
29
|
+
- **`Ractor::Wrapper`** — Public API. Wraps an object and manages its lifecycle. Accepts options like `use_current_ractor:`, `threads:`, `name:`, and per-method settings via `configure_method`.
|
|
30
|
+
- **`Ractor::Wrapper::Stub`** — Frozen, shareable proxy passed to other Ractors. Uses `method_missing` to forward calls back to the wrapper via message passing.
|
|
31
|
+
- **`Ractor::Wrapper::MethodSettings`** — Frozen configuration controlling copy vs. move semantics for arguments and return values, and block handling behavior.
|
|
32
|
+
- **`Ractor::Wrapper::Server`** — Private backend. Receives `CallMessage` objects and dispatches them to the wrapped object, then returns results via `ReturnMessage`, `ExceptionMessage`, or `YieldMessage`.
|
|
33
|
+
|
|
34
|
+
### Two execution modes
|
|
35
|
+
|
|
36
|
+
1. **Isolated mode** (default) — the wrapped object is moved into a new Ractor. Other Ractors interact with it through the Stub. After `join`, the object can be recovered via `recover_object`.
|
|
37
|
+
2. **Local mode** (`use_current_ractor: true`) — the server runs as Thread(s) inside the current Ractor. The object is never moved. Used for objects that cannot be transferred between Ractors (e.g., SQLite3 connections).
|
|
38
|
+
|
|
39
|
+
### Concurrency within the server
|
|
40
|
+
|
|
41
|
+
- **Sequential** (default) — one call at a time, no worker threads.
|
|
42
|
+
- **Concurrent** — multiple worker threads (set via `threads:`), for thread-safe wrapped objects.
|
|
43
|
+
|
|
44
|
+
### Message protocol
|
|
45
|
+
|
|
46
|
+
All inter-Ractor communication uses frozen message structs defined in the file: `CallMessage`, `ReturnMessage`, `ExceptionMessage`, `YieldMessage`, `StopMessage`, `JoinMessage`, `WorkerStoppedMessage`. Block calls round-trip: the server sends a `YieldMessage` to the caller Ractor, the caller executes the block and sends back a result or exception.
|
|
47
|
+
|
|
48
|
+
### Lifecycle
|
|
49
|
+
|
|
50
|
+
1. Wrapper starts → Server enters **running** phase (accepts calls).
|
|
51
|
+
2. `async_stop` or `stop` called → Server enters **stopping** phase (rejects new calls, drains workers).
|
|
52
|
+
3. All workers finish → Server enters **cleanup** phase and shuts down.
|
|
53
|
+
4. `join` returns → In isolated mode, `recover_object` retrieves the wrapped object.
|
|
54
|
+
|
|
55
|
+
## Code Style
|
|
56
|
+
|
|
57
|
+
- Ruby 4.0+ target
|
|
58
|
+
- Double-quoted strings (`Style/StringLiterals: double_quotes`)
|
|
59
|
+
- Trailing commas in multiline arrays and hashes
|
|
60
|
+
- Bracket-style symbol and word arrays (`[:foo, :bar]` not `%i[foo bar]`)
|
|
61
|
+
- Max line length: 120
|
|
62
|
+
- `Style/DocumentationMethod: Enabled` — public methods require YARD docs
|
|
63
|
+
- Tests use Minitest spec style with assertions (not expectations)
|
|
64
|
+
- Top-level constants must be prefixed with `::` (e.g. `::File`, `::Regexp`, `::Gem::Version`) to avoid ambiguous resolution within nested namespaces. Relative constants defined within the current namespace should not be prefixed. Note that Kernel method calls such as `Array(x)`, `Integer(x)`, `Float(x)` look like constants but are not and do not get the prefix.
|
|
65
|
+
|
|
66
|
+
## Testing
|
|
67
|
+
|
|
68
|
+
- Minitest spec style: `describe`/`it` blocks with `assert_*` assertions (not expectations)
|
|
69
|
+
- Test files follow the `test_*.rb` naming convention
|
|
70
|
+
|
|
71
|
+
## General coding instructions
|
|
72
|
+
|
|
73
|
+
- Unless instructed otherwise, always use red-green test-driven development when making code changes. For each step in a coding task, first write tests and confirm they fail. Then write code to make the tests pass.
|
|
74
|
+
- Unless instructed otherwise, always git commit after a step is complete and the tests pass.
|
|
75
|
+
- Conventional Commits format required (`fix:`, `feat:`, `docs:`, etc.)
|
|
76
|
+
- Prefer Ruby for any one-off scripts you need to write as part of your work.
|