Skip to content

Commit 209f17c

Browse files
committed
Bump minor version.
1 parent 235425e commit 209f17c

File tree

5 files changed

+184
-9
lines changed

5 files changed

+184
-9
lines changed

context/getting-started.md

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# Getting Started
2+
3+
This guide explains how to use `async-actor` for asynchronous programming.
4+
5+
## Installation
6+
7+
Add the gem to your project:
8+
9+
~~~ bash
10+
$ bundle add async-actor
11+
~~~
12+
13+
## Core Concepts
14+
15+
`async-actor` provides a simple actor model where each actor runs in its own dedicated thread. The {ruby Async::Actor::Proxy} class creates a proxy interface that wraps any object and executes its methods asynchronously in a separate thread, using an event loop. When you call methods on the proxy, they are queued and processed by the internal actor thread, allowing for concurrent execution while maintaining thread isolation.
16+
17+
### Lifecycle Separation
18+
19+
One of the key benefits of actors is **lifecycle separation**. An actor can run for the entire lifetime of your process, independent of your application's async contexts. This means you can have long-running actors that persist even while your frontend usage of Async may start and stop multiple times.
20+
21+
For example, you might have a logging actor or database connection pool that runs continuously, while your web server or other components restart their async contexts as needed. The actor maintains its own thread and state, providing a stable foundation for your application's infrastructure. A common use case is in test suites where you need to cache access to background connection pools for performance reasons - you can create an actor that manages database connections or external service clients, allowing you to reuse these expensive resources between tests while each test runs in its own isolated async context.
22+
23+
## Usage
24+
25+
Any existing object can be wrapped into an actor:
26+
27+
```ruby
28+
require "async/actor"
29+
30+
require "cgi"
31+
require "net/http"
32+
require "json"
33+
34+
class Wikipedia
35+
def summary_url(title)
36+
URI "https://en.wikipedia.org/api/rest_v1/page/summary/#{CGI.escape title}"
37+
end
38+
39+
def lookup(title)
40+
JSON.parse(Net::HTTP.get(summary_url(title))).fetch("extract")
41+
end
42+
end
43+
44+
wikipedia = Async::Actor.new(Wikipedia.new)
45+
46+
puts wikipedia.lookup("Ruby_(programming_language)")
47+
```
48+
49+
The above code looks deceptively simple, however `wikipedia.lookup` actually sends a message to the actor using a message queue. The proxy creates a dedicated thread that runs an async event loop, and the actor processes the message within this thread. This allows the actor to handle multiple messages concurrently within its own thread while keeping it isolated from the main thread. When the result is ready, the actor thread notifies the caller with the result.
50+
51+
Be aware that as the actor is running in a separate thread, your code will need to be thread-safe, including arguments that you pass to the actor. Any block you provide will also be executed in the actor's thread.
52+
53+
## Return Value Control
54+
55+
The actor proxy provides flexible control over how method calls return values through the `return_value` parameter. This parameter accepts three options:
56+
57+
### `:wait` (Default)
58+
59+
By default, method calls block until the result is available and return the actual result:
60+
61+
```ruby
62+
wikipedia = Async::Actor.new(Wikipedia.new)
63+
64+
# This blocks until the lookup completes and returns the extract
65+
result = wikipedia.lookup("Ruby_(programming_language)")
66+
puts result # Prints the Wikipedia extract
67+
```
68+
69+
This is equivalent to:
70+
71+
```ruby
72+
result = wikipedia.lookup("Ruby_(programming_language)", return_value: :wait)
73+
```
74+
75+
### `:promise`
76+
77+
Returns an `Async::Promise` immediately, allowing you to wait for the result later:
78+
79+
```ruby
80+
wikipedia = Async::Actor.new(Wikipedia.new)
81+
82+
# Returns immediately with a promise
83+
promise = wikipedia.lookup("Ruby_(programming_language)", return_value: :promise)
84+
85+
# Do other work...
86+
puts "Looking up information..."
87+
88+
# Wait for the result when needed
89+
result = promise.wait
90+
puts result
91+
```
92+
93+
This is useful for fire-and-forget operations or when you want to start multiple operations concurrently:
94+
95+
```ruby
96+
# Start multiple lookups concurrently
97+
ruby_promise = wikipedia.lookup("Ruby_(programming_language)", return_value: :promise)
98+
python_promise = wikipedia.lookup("Python_(programming_language)", return_value: :promise)
99+
java_promise = wikipedia.lookup("Java_(programming_language)", return_value: :promise)
100+
101+
# Wait for all results
102+
puts "Ruby: #{ruby_promise.wait}"
103+
puts "Python: #{python_promise.wait}"
104+
puts "Java: #{java_promise.wait}"
105+
```
106+
107+
### `:ignore`
108+
109+
Executes the method but discards the result, returning `nil` immediately:
110+
111+
```ruby
112+
logger = Async::Actor.new(Logger.new)
113+
114+
# Fire-and-forget logging - returns nil immediately
115+
logger.info("Application started", return_value: :ignore)
116+
117+
# Continue with other work without waiting
118+
puts "Continuing execution..."
119+
```
120+
121+
This is perfect for logging, notifications, or other side-effect operations where you don't need the return value.
122+
123+
## Error Handling
124+
125+
Errors from actor method calls are propagated to the caller:
126+
127+
```ruby
128+
wikipedia = Async::Actor.new(Wikipedia.new)
129+
130+
begin
131+
# This will raise if the network request fails
132+
result = wikipedia.lookup("NonexistentPage")
133+
rescue => error
134+
puts "Lookup failed: #{error.message}"
135+
end
136+
```
137+
138+
With promises, errors are raised when you call `wait`:
139+
140+
```ruby
141+
promise = wikipedia.lookup("NonexistentPage", return_value: :promise)
142+
143+
begin
144+
result = promise.wait
145+
rescue => error
146+
puts "Lookup failed: #{error.message}"
147+
end
148+
```

context/index.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Automatically generated context index for Utopia::Project guides.
2+
# Do not edit then files in this directory directly, instead edit the guides and then run `bake utopia:project:agent:context:update`.
3+
---
4+
description: A multi-threaded actor implementation where each actor has it's own event
5+
loop.
6+
metadata:
7+
documentation_uri: https://socketry.github.io/async-actor/
8+
funding_uri: https://github.com/sponsors/ioquatix
9+
source_code_uri: https://github.com/socketry/async-actor.git
10+
files:
11+
- path: getting-started.md
12+
title: Getting Started
13+
description: This guide explains how to use `async-actor` for asynchronous programming.

lib/async/actor/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55

66
module Async
77
module Actor
8-
VERSION = "0.1.1"
8+
VERSION = "0.2.0"
99
end
1010
end

readme.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,21 @@ Please see the [project documentation](https://socketry.github.io/async-actor/)
1818

1919
## Releases
2020

21-
There are no documented releases.
21+
Please see the [project releases](https://socketry.github.io/async-actor/releases/index) for all releases.
22+
23+
### v0.2.0
24+
25+
### v0.1.1
26+
27+
- Fix dependency on async gem to use `>= 1` instead of `~> 1` for better compatibility.
28+
- Update guide links in documentation.
29+
30+
### v0.1.0
31+
32+
- Initial release of async-actor gem.
33+
- Core actor model implementation with `Async::Actor` class.
34+
- Proxy class for safe cross-actor communication.
35+
- Variable class for thread-safe value storage and updates.
2236

2337
## Contributing
2438

releases.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
# Releases
22

3-
## Unreleased
3+
## v0.2.0
44

55
## v0.1.1
66

7-
- Fix dependency on async gem to use `>= 1` instead of `~> 1` for better compatibility.
8-
- Update guide links in documentation.
7+
- Fix dependency on async gem to use `>= 1` instead of `~> 1` for better compatibility.
8+
- Update guide links in documentation.
99

1010
## v0.1.0
1111

12-
- Initial release of async-actor gem.
13-
- Core actor model implementation with `Async::Actor` class.
14-
- Proxy class for safe cross-actor communication.
15-
- Variable class for thread-safe value storage and updates.
12+
- Initial release of async-actor gem.
13+
- Core actor model implementation with `Async::Actor` class.
14+
- Proxy class for safe cross-actor communication.
15+
- Variable class for thread-safe value storage and updates.

0 commit comments

Comments
 (0)