11### Simple asynchronous task
22
33future = Concurrent . future { sleep 0.1 ; 1 + 1 } # evaluation starts immediately
4- # => <#Concurrent::Edge::Future:0x7fd41a956d70 pending blocks:[]>
4+ # => <#Concurrent::Edge::Future:0x7fc6218f2318 pending blocks:[]>
55future . completed? # => false
66# block until evaluated
77future . value # => 2
1111### Failing asynchronous task
1212
1313future = Concurrent . future { raise 'Boom' }
14- # => <#Concurrent::Edge::Future:0x7fd41a946c18 failed blocks:[]>
14+ # => <#Concurrent::Edge::Future:0x7fc6218eae38 pending blocks:[]>
1515future . value # => nil
1616future . value! rescue $! # => #<RuntimeError: Boom>
1717future . reason # => #<RuntimeError: Boom>
4141Concurrent . future { 1 } . then ( &:succ ) . rescue { |e | e . message } . then ( &:succ ) . value
4242 # => 3
4343
44+ failing_zip = Concurrent . completed_future ( 1 ) & Concurrent . future { raise 'boom' }
45+ # => <#Concurrent::Edge::Future:0x7fc6218b0f08 pending blocks:[]>
46+ failing_zip . result # => [false, [1, nil], [nil, #<RuntimeError: boom>]]
47+ failing_zip . then { |v | 'never happens' } . result # => [false, [1, nil], [nil, #<RuntimeError: boom>]]
48+ failing_zip . rescue { |a , b | ( a || b ) . message } . value
49+ # => "boom"
50+ failing_zip . chain { |success , values , reasons | [ success , values . compact , reasons . compactß ] } . value
51+ # => nil
4452
4553### Delay
4654
4755# will not evaluate until asked by #value or other method requiring completion
4856future = Concurrent . delay { 'lazy' }
49- # => <#Concurrent::Edge::Future:0x7fd41a8f6ec0 pending blocks:[]>
57+ # => <#Concurrent::Edge::Future:0x7fc6218a37e0 pending blocks:[]>
5058sleep 0.1
5159future . completed? # => false
5260future . value # => "lazy"
5361
5462# propagates trough chain allowing whole or partial lazy chains
5563
5664head = Concurrent . delay { 1 }
57- # => <#Concurrent::Edge::Future:0x7fd41a8ee1a8 pending blocks:[]>
65+ # => <#Concurrent::Edge::Future:0x7fc6218a0720 pending blocks:[]>
5866branch1 = head . then ( &:succ )
59- # => <#Concurrent::Edge::Future:0x7fd41a8ed438 pending blocks:[]>
67+ # => <#Concurrent::Edge::Future:0x7fc6212c7b50 pending blocks:[]>
6068branch2 = head . delay . then ( &:succ )
61- # => <#Concurrent::Edge::Future:0x7fd41a8e7588 pending blocks:[]>
69+ # => <#Concurrent::Edge::Future:0x7fc6212c6098 pending blocks:[]>
6270join = branch1 & branch2
63- # => <#Concurrent::Edge::Future:0x7fd41a8e4ec8 pending blocks:[]>
71+ # => <#Concurrent::Edge::Future:0x7fc6212c4f40 pending blocks:[]>
6472
6573sleep 0.1 # nothing will complete # => 0
6674[ head , branch1 , branch2 , join ] . map ( &:completed? ) # => [false, false, false, false]
8896### Schedule
8997
9098scheduled = Concurrent . schedule ( 0.1 ) { 1 }
91- # => <#Concurrent::Edge::Future:0x7fd41a8a4468 pending blocks:[]>
99+ # => <#Concurrent::Edge::Future:0x7fc62128c550 pending blocks:[]>
92100
93101scheduled . completed? # => false
94102scheduled . value # available after 0.1sec # => 1
95103
96104# and in chain
97105scheduled = Concurrent . delay { 1 } . schedule ( 0.1 ) . then ( &:succ )
98- # => <#Concurrent::Edge::Future:0x7fd41a895828 pending blocks:[]>
106+ # => <#Concurrent::Edge::Future:0x7fc6228bcdc0 pending blocks:[]>
99107# will not be scheduled until value is requested
100108sleep 0.1
101109scheduled . value # returns after another 0.1sec # => 2
104112### Completable Future and Event
105113
106114future = Concurrent . future
107- # => <#Concurrent::Edge::CompletableFuture:0x7fd41a87c648 pending blocks:[]>
115+ # => <#Concurrent::Edge::CompletableFuture:0x7fc623083720 pending blocks:[]>
108116event = Concurrent . event
109- # => <#Concurrent::Edge::CompletableEvent:0x7fd41a8770d0 pending blocks:[]>
117+ # => <#Concurrent::Edge::CompletableEvent:0x7fc623081100 pending blocks:[]>
110118# Don't forget to keep the reference, `Concurrent.future.then { |v| v }` is incompletable
111119
112120# will be blocked until completed
113121t1 = Thread . new { future . value }
114122t2 = Thread . new { event . wait }
115123
116124future . success 1
117- # => <#Concurrent::Edge::CompletableFuture:0x7fd41a87c648 success blocks:[]>
125+ # => <#Concurrent::Edge::CompletableFuture:0x7fc623083720 success blocks:[]>
118126future . success 1 rescue $!
119127 # => #<Concurrent::MultipleAssignmentError: Future can be completed only once. Current result is [true, 1, nil], trying to set [true, 1, nil]>
120128future . try_success 2 # => false
121129event . complete
122- # => <#Concurrent::Edge::CompletableEvent:0x7fd41a8770d0 completed blocks:[]>
130+ # => <#Concurrent::Edge::CompletableEvent:0x7fc623081100 completed blocks:[]>
123131
124132[ t1 , t2 ] . each &:join
125133
126134
127135### Callbacks
128136
129- queue = Queue . new # => #<Thread::Queue:0x007fd41b0543e8 >
137+ queue = Queue . new # => #<Thread::Queue:0x007fc62127df00 >
130138future = Concurrent . delay { 1 + 1 }
131- # => <#Concurrent::Edge::Future:0x7fd41b04f028 pending blocks:[]>
139+ # => <#Concurrent::Edge::Future:0x7fc62127c060 pending blocks:[]>
132140
133141future . on_success { queue << 1 } # evaluated asynchronously
134- # => <#Concurrent::Edge::Future:0x7fd41b04f028 pending blocks:[]>
142+ # => <#Concurrent::Edge::Future:0x7fc62127c060 pending blocks:[]>
135143future . on_success! { queue << 2 } # evaluated on completing thread
136- # => <#Concurrent::Edge::Future:0x7fd41b04f028 pending blocks:[]>
144+ # => <#Concurrent::Edge::Future:0x7fc62127c060 pending blocks:[]>
137145
138146queue . empty? # => true
139147future . value # => 2
144152### Thread-pools
145153
146154Concurrent . future ( :fast ) { 2 } . then ( :io ) { File . read __FILE__ } . wait
147- # => <#Concurrent::Edge::Future:0x7fd41a857550 success blocks:[]>
155+ # => <#Concurrent::Edge::Future:0x7fc62125d9a8 success blocks:[]>
148156
149157
150158### Interoperability with actors
151159
152160actor = Concurrent ::Actor ::Utils ::AdHoc . spawn :square do
153161 -> v { v ** 2 }
154162end
155- # => #<Concurrent::Actor::Reference:0x7fd41c03b5b8 /square (Concurrent::Actor::Utils::AdHoc)>
163+ # => #<Concurrent::Actor::Reference:0x7fc621234a30 /square (Concurrent::Actor::Utils::AdHoc)>
156164
157165Concurrent .
158166 future { 2 } .
165173
166174### Interoperability with channels
167175
168- ch1 = Concurrent ::Edge ::Channel . new # => #<Concurrent::Edge::Channel:0x007fd41a297458 >
169- ch2 = Concurrent ::Edge ::Channel . new # => #<Concurrent::Edge::Channel:0x007fd41a296940 >
176+ ch1 = Concurrent ::Edge ::Channel . new # => #<Concurrent::Edge::Channel:0x007fc621205460 >
177+ ch2 = Concurrent ::Edge ::Channel . new # => #<Concurrent::Edge::Channel:0x007fc6212041c8 >
170178
171179result = Concurrent . select ( ch1 , ch2 )
172- # => <#Concurrent::Edge::CompletableFuture:0x7fd41a295c98 pending blocks:[]>
180+ # => <#Concurrent::Edge::CompletableFuture:0x7fc6211fe5c0 pending blocks:[]>
173181ch1 . push 1 # => nil
174182result . value!
175- # => [1, #<Concurrent::Edge::Channel:0x007fd41a297458 >]
183+ # => [1, #<Concurrent::Edge::Channel:0x007fc621205460 >]
176184
177185Concurrent .
178186 future { 1 +1 } .
179187 then_push ( ch1 )
180- # => <#Concurrent::Edge::Future:0x7fd41a284010 pending blocks:[]>
188+ # => <#Concurrent::Edge::Future:0x7fc6211f7338 pending blocks:[]>
181189result = Concurrent .
182190 future { '%02d' } .
183191 then_select ( ch1 , ch2 ) .
184192 then { |format , ( value , channel ) | format format , value }
185- # => <#Concurrent::Edge::Future:0x7fd41a25d938 pending blocks:[]>
193+ # => <#Concurrent::Edge::Future:0x7fc6211ec668 pending blocks:[]>
186194result . value! # => "02"
187195
188196
189197### Common use-cases Examples
190198
191199# simple background processing
192200Concurrent . future { do_stuff }
193- # => <#Concurrent::Edge::Future:0x7fd41a23d520 pending blocks:[]>
201+ # => <#Concurrent::Edge::Future:0x7fc6211df170 pending blocks:[]>
194202
195203# parallel background processing
196204jobs = 10 . times . map { |i | Concurrent . future { i } }
@@ -207,7 +215,7 @@ def schedule_job
207215end # => :schedule_job
208216
209217schedule_job
210- # => <#Concurrent::Edge::Future:0x7fd41a2245e8 pending blocks:[]>
218+ # => <#Concurrent::Edge::Future:0x7fc62119c140 pending blocks:[]>
211219@end = true # => true
212220
213221
@@ -220,7 +228,7 @@ def schedule_job
220228 data [ message ]
221229 end
222230end
223- # => #<Concurrent::Actor::Reference:0x7fd41a206228 /db (Concurrent::Actor::Utils::AdHoc)>
231+ # => #<Concurrent::Actor::Reference:0x7fc62117f568 /db (Concurrent::Actor::Utils::AdHoc)>
224232
225233concurrent_jobs = 11 . times . map do |v |
226234 Concurrent .
@@ -250,7 +258,7 @@ def schedule_job
250258 end
251259 end
252260end
253- # => #<Concurrent::Actor::Reference:0x7fd41a0530c0 /DB-pool (Concurrent::Actor::Utils::Pool)>
261+ # => #<Concurrent::Actor::Reference:0x7fc6218969f0 /DB-pool (Concurrent::Actor::Utils::Pool)>
254262
255263concurrent_jobs = 11 . times . map do |v |
256264 Concurrent .
0 commit comments