Skip to content

Commit 0884683

Browse files
committed
Add documentation.
1 parent 8242115 commit 0884683

File tree

4 files changed

+101
-36
lines changed

4 files changed

+101
-36
lines changed

guides/getting-started/readme.md

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Getting Started
2+
3+
This guide explains how to use `async-await` for implementing some common concurrency patterns.
4+
5+
## Installation
6+
7+
Add the gem to your project:
8+
9+
~~~ bash
10+
$ bundle add async-await
11+
~~~
12+
13+
## Usage
14+
15+
### "async" Keyword
16+
17+
This gem provides {ruby Async::Await} which introduces the `async` keyword. This keyword is used to define asynchronous methods. The method will return an `Async::Task` object, which can be waited on to get the result.
18+
19+
``` ruby
20+
require 'async/await'
21+
22+
class Coop
23+
include Async::Await
24+
25+
async def count_chickens(area_name)
26+
3.times do |i|
27+
sleep rand
28+
29+
puts "Found a chicken in the #{area_name}!"
30+
end
31+
end
32+
33+
async def count_all_chickens
34+
# These methods all run at the same time.
35+
count_chickens("garden")
36+
count_chickens("house")
37+
38+
# We wait for the result
39+
count_chickens("tree").wait
40+
end
41+
end
42+
43+
coop = Coop.new
44+
coop.count_all_chickens
45+
```
46+
47+
This interface was originally designed as a joke, but may be useful in some limited contexts. It is not recommended for general use.
48+
49+
### Enumerable
50+
51+
This gem provides {ruby Async::Await::Enumerable} which adds async support to the `Enumerable` module. This allows you to use concurrency in a more functional style.
52+
53+
``` ruby
54+
require "async/await/enumerable"
55+
56+
[1, 2, 3].async_each do |i|
57+
sleep rand
58+
puts i
59+
end
60+
```
61+
62+
This will run the block for each element in the array concurrently.
63+
64+
#### Using a Semaphore
65+
66+
In order to prevent unlimited concurrency, you can use a semaphore to limit the number of concurrent tasks. This is useful when you want to limit the number of concurrent tasks to a specific number.
67+
68+
``` ruby
69+
require "async/await/enumerable"
70+
require "async/semaphore"
71+
72+
semaphore = Async::Semaphore.new(2)
73+
74+
[1, 2, 3].async_each(parent: semaphore) do |i|
75+
sleep rand
76+
puts i
77+
end
78+
```

lib/async/await.rb

+13
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,18 @@
55

66
require_relative "await/version"
77

8+
# @namespace
89
module Async
10+
# Provide a way to wrap methods so that they can be run synchronously or asynchronously in an event loop.
911
module Await
12+
# A hook that is called when the module is included in a class in order to provide the class with the methods defined in this module.
1013
def self.included(klass)
1114
klass.extend(self)
1215
end
1316

17+
# Wrap the method with the given name in a block that will run the method synchronously in an event loop.
18+
#
19+
# @parameter name [Symbol] The name of the method to wrap.
1420
def sync(name)
1521
original_method = instance_method(name)
1622

@@ -25,8 +31,13 @@ def sync(name)
2531
end.wait
2632
end
2733
end
34+
35+
return name
2836
end
2937

38+
# Wrap the method with the given name in a block that will run the method asynchronously in an event loop.
39+
#
40+
# @parameter name [Symbol] The name of the method to wrap.
3041
def async(name)
3142
original_method = instance_method(name)
3243

@@ -37,6 +48,8 @@ def async(name)
3748
original_method.bind(self).call(*arguments, &block)
3849
end
3950
end
51+
52+
return name
4053
end
4154
end
4255
end

lib/async/await/enumerable.rb

+10
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@
77

88
module Async
99
module Await
10+
# Provide asynchronous methods for enumerables.
1011
module Enumerable
12+
# This method is used to map the elements of an enumerable collection asynchronously.
13+
#
14+
# @parameter parent [Interface(:async)] The parent to use for creating new tasks.
15+
# @yields {|item| ...} The block to execute for each element in the collection.
1116
def async_map(parent: nil, &block)
1217
Sync do |task|
1318
parent ||= task
@@ -20,6 +25,11 @@ def async_map(parent: nil, &block)
2025
end
2126
end
2227

28+
# This method is used to iterate over the elements of an enumerable collection asynchronously.
29+
#
30+
# @parameter parent [Interface(:async)] The parent to use for creating new tasks.
31+
# @yields {|item| ...} The block to execute for each element in the collection.
32+
# @return [self] The original enumerable collection.
2333
def async_each(parent: nil, &block)
2434
Sync do |task|
2535
parent ||= task

readme.md

-36
Original file line numberDiff line numberDiff line change
@@ -4,44 +4,8 @@ Implements the async/await pattern for Ruby using [async](https://github.com/soc
44

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

7-
## Installation
8-
9-
``` shell
10-
bundle add async-await
11-
```
12-
137
## Usage
148

15-
In any asynchronous context (e.g. a reactor), simply use the `await` function like so:
16-
17-
``` ruby
18-
require 'async/await'
19-
20-
class Coop
21-
include Async::Await
22-
23-
async def count_chickens(area_name)
24-
3.times do |i|
25-
sleep rand
26-
27-
puts "Found a chicken in the #{area_name}!"
28-
end
29-
end
30-
31-
async def count_all_chickens
32-
# These methods all run at the same time.
33-
count_chickens("garden")
34-
count_chickens("house")
35-
36-
# We wait for the result
37-
count_chickens("tree").wait
38-
end
39-
end
40-
41-
coop = Coop.new
42-
coop.count_all_chickens
43-
```
44-
459
## Contributing
4610

4711
We welcome contributions to this project.

0 commit comments

Comments
 (0)