Skip to content

Commit 248762b

Browse files
committed
update primises md documentation
1 parent de57bad commit 248762b

File tree

4 files changed

+227
-290
lines changed

4 files changed

+227
-290
lines changed

doc/format-md.rb

Lines changed: 0 additions & 122 deletions
This file was deleted.

doc/promises.in.md

Lines changed: 79 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,71 @@
11
# Promises Framework
22

3-
Promises is a new framework unifying former `Concurrent::Future`, `Concurrent::Promise`, `Concurrent::IVar`,
4-
`Concurrent::Event`, `Concurrent.dataflow`, `Delay`, and `TimerTask`. It extensively uses the new
5-
synchronization layer to make all the features **non-blocking** and
6-
**lock-free**, with the exception of obviously blocking operations like
7-
`#wait`, `#value`. As a result it lowers a danger of deadlocking and offers
3+
Promises is a new framework unifying former `Concurrent::Future`,
4+
`Concurrent::Promise`, `Concurrent::IVar`, `Concurrent::Event`,
5+
`Concurrent.dataflow`, `Delay`, and `TimerTask`. It extensively uses the new
6+
synchronization layer to make all the features *non-blocking* and
7+
*lock-free*, with the exception of obviously blocking operations like
8+
`#wait`, `#value`, etc. As a result it lowers a danger of deadlocking and offers
89
better performance.
910

1011
## Overview
1112

12-
There are two central classes ... TODO
13+
*TODO*
1314

14-
## Where does it executes?
15-
16-
- TODO Explain `_on` `_using` sufixes.
15+
- What is it?
16+
- What is it for?
17+
- Main classes {Future}, {Event}
18+
- Explain `_on` `_using` suffixes.
1719

1820
## Old examples follow
1921

2022
*TODO rewrite into md with examples*
2123

22-
Adds factory methods like: future, event, delay, schedule, zip, etc. Otherwise
23-
they can be called on Promises module.
24+
Constructors are not accessible, instead there are many constructor methods in
25+
FactoryMethods.
2426

2527
```ruby
2628
Concurrent::Promises::FactoryMethods.instance_methods false
29+
```
30+
31+
The module can be included or extended where needed.
32+
33+
```ruby
34+
Class.new do
35+
include Concurrent::Promises::FactoryMethods
36+
37+
def a_method
38+
resolvable_event
39+
end
40+
end.new.a_method
2741

42+
Module.new { extend Concurrent::Promises::FactoryMethods }.resolvable_event
43+
```
44+
The module is already extended into {Promises} for convenience.
45+
46+
```ruby
47+
Concurrent::Promises.resolvable_event
48+
```
49+
50+
For this guide we include the module into `main` so we can call the factory
51+
methods in following examples directly.
52+
53+
```ruby
2854
include Concurrent::Promises::FactoryMethods #
55+
resolvable_event
2956
```
3057

3158
Simple asynchronous task:
3259

3360
```ruby
3461
future = future(0.1) { |duration| sleep duration; :result } # evaluation starts immediately
35-
future.completed?
62+
future.resolved?
3663
# block until evaluated
3764
future.value
38-
future.completed?
65+
future.resolved?
3966
```
4067

41-
Failing asynchronous task
68+
Rejecting asynchronous task
4269

4370
```ruby
4471
future = future { raise 'Boom' }
@@ -49,15 +76,15 @@ future.reason
4976
raise future rescue $!
5077
```
5178

52-
Direct creation of completed futures
79+
Direct creation of resolved futures
5380

5481
```ruby
55-
succeeded_future(Object.new)
56-
failed_future(StandardError.new("boom"))
82+
fulfilled_future(Object.new)
83+
rejected_future(StandardError.new("boom"))
5784

5885
### Chaining of futures
5986

60-
head = succeeded_future 1 #
87+
head = fulfilled_future 1 #
6188
branch1 = head.then(&:succ) #
6289
branch2 = head.then(&:succ).then(&:succ) #
6390
branch1.zip(branch2).value!
@@ -66,7 +93,7 @@ branch1.zip(branch2).value!
6693
(branch1 & branch2).then(&:+).value!
6794
# or a class method zip from FactoryMethods can be used to zip multiple futures
6895
zip(branch1, branch2, branch1).then { |*values| values.reduce &:+ }.value!
69-
# pick only first completed
96+
# pick only first resolved
7097
any(branch1, branch2).value!
7198
(branch1 | branch2).value!
7299

@@ -76,29 +103,29 @@ any(branch1, branch2).value!
76103
# any supplied arguments are passed to the block, promises ensure that they are visible to the block
77104

78105
future('3') { |s| s.to_i }.then(2) { |a, b| a + b }.value
79-
succeeded_future(1).then(2, &:+).value
80-
succeeded_future(1).chain(2) { |success, value, reason, arg| value + arg }.value
106+
fulfilled_future(1).then(2, &:+).value
107+
fulfilled_future(1).chain(2) { |fulfilled, value, reason, arg| value + arg }.value
81108

82109

83110
### Error handling
84111

85-
succeeded_future(Object.new).then(&:succ).then(&:succ).rescue { |e| e.class }.value # error propagates
86-
succeeded_future(Object.new).then(&:succ).rescue { 1 }.then(&:succ).value # rescued and replaced with 1
87-
succeeded_future(1).then(&:succ).rescue { |e| e.message }.then(&:succ).value # no error, rescue not applied
112+
fulfilled_future(Object.new).then(&:succ).then(&:succ).rescue { |e| e.class }.value # error propagates
113+
fulfilled_future(Object.new).then(&:succ).rescue { 1 }.then(&:succ).value # rescued and replaced with 1
114+
fulfilled_future(1).then(&:succ).rescue { |e| e.message }.then(&:succ).value # no error, rescue not applied
88115

89-
failing_zip = succeeded_future(1) & failed_future(StandardError.new('boom'))
90-
failing_zip.result
91-
failing_zip.then { |v| 'never happens' }.result
92-
failing_zip.rescue { |a, b| (a || b).message }.value
93-
failing_zip.chain { |success, values, reasons| [success, values.compact, reasons.compactß] }.value
116+
rejected_zip = fulfilled_future(1) & rejected_future(StandardError.new('boom'))
117+
rejected_zip.result
118+
rejected_zip.then { |v| 'never happens' }.result
119+
rejected_zip.rescue { |a, b| (a || b).message }.value
120+
rejected_zip.chain { |fulfilled, values, reasons| [fulfilled, values.compact, reasons.compact] }.value
94121

95122

96123
### Delay
97124

98-
# will not evaluate until asked by #value or other method requiring completion
125+
# will not evaluate until asked by #value or other method requiring resolution
99126
future = delay { 'lazy' }
100127
sleep 0.1 #
101-
future.completed?
128+
future.resolved?
102129
future.value
103130

104131
# propagates trough chain allowing whole or partial lazy chains
@@ -108,15 +135,15 @@ branch1 = head.then(&:succ)
108135
branch2 = head.delay.then(&:succ)
109136
join = branch1 & branch2
110137

111-
sleep 0.1 # nothing will complete
112-
[head, branch1, branch2, join].map(&:completed?)
138+
sleep 0.1 # nothing will resolve
139+
[head, branch1, branch2, join].map(&:resolved?)
113140

114141
branch1.value
115-
sleep 0.1 # forces only head to complete, branch 2 stays incomplete
116-
[head, branch1, branch2, join].map(&:completed?)
142+
sleep 0.1 # forces only head to resolve, branch 2 stays pending
143+
[head, branch1, branch2, join].map(&:resolved?)
117144

118145
join.value
119-
[head, branch1, branch2, join].map(&:completed?)
146+
[head, branch1, branch2, join].map(&:resolved?)
120147

121148

122149
### Flatting
@@ -136,7 +163,7 @@ future { future { future { 1 + 1 } } }.
136163
# it'll be executed after 0.1 seconds
137164
scheduled = schedule(0.1) { 1 }
138165

139-
scheduled.completed?
166+
scheduled.resolved?
140167
scheduled.value # available after 0.1sec
141168

142169
# and in chain
@@ -146,19 +173,19 @@ sleep 0.1 #
146173
scheduled.value # returns after another 0.1sec
147174

148175

149-
### Completable Future and Event
176+
### Resolvable Future and Event
150177

151-
future = completable_future
152-
event = completable_event()
178+
future = resolvable_future
179+
event = resolvable_event()
153180

154-
# These threads will be blocked until the future and event is completed
181+
# These threads will be blocked until the future and event is resolved
155182
t1 = Thread.new { future.value } #
156183
t2 = Thread.new { event.wait } #
157184

158-
future.success 1
159-
future.success 1 rescue $!
160-
future.success 2, false
161-
event.complete
185+
future.fulfill 1
186+
future.fulfill 1 rescue $!
187+
future.fulfill 2, false
188+
event.resolve
162189

163190
# The threads can be joined now
164191
[t1, t2].each &:join #
@@ -169,8 +196,8 @@ event.complete
169196
queue = Queue.new
170197
future = delay { 1 + 1 }
171198

172-
future.on_success { queue << 1 } # evaluated asynchronously
173-
future.on_success! { queue << 2 } # evaluated on completing thread
199+
future.on_fulfillment { queue << 1 } # evaluated asynchronously
200+
future.on_fulfillment! { queue << 2 } # evaluated on resolving thread
174201

175202
queue.empty?
176203
future.value
@@ -236,8 +263,8 @@ zip(*jobs).value
236263
# periodic task
237264
def schedule_job(interval, &job)
238265
# schedule the first execution and chain restart og the job
239-
Concurrent.schedule(interval, &job).chain do |success, continue, reason|
240-
if success
266+
Concurrent.schedule(interval, &job).chain do |fulfilled, continue, reason|
267+
if fulfilled
241268
schedule_job(interval, &job) if continue
242269
else
243270
# handle error
@@ -281,10 +308,10 @@ end
281308

282309
concurrent_jobs = 11.times.map do |v|
283310

284-
succeeded_future(v).
311+
fulfilled_future(v).
285312
# ask the DB with the `v`, only one at the time, rest is parallel
286313
then_ask(DB).
287-
# get size of the string, fails for 11
314+
# get size of the string, rejects for 11
288315
then(&:size).
289316
rescue { |reason| reason.message } # translate error to value (exception, message)
290317
end #
@@ -308,7 +335,7 @@ end
308335

309336
concurrent_jobs = 11.times.map do |v|
310337

311-
succeeded_future(v).
338+
fulfilled_future(v).
312339
# ask the DB_POOL with the `v`, only 5 at the time, rest is parallel
313340
then_ask(DB_POOL).
314341
then(&:size).
File renamed without changes.

0 commit comments

Comments
 (0)