Skip to content

Commit b961f88

Browse files
committed
Better docs and minor function renaming.
1 parent f8bbbc8 commit b961f88

File tree

5 files changed

+67
-15
lines changed

5 files changed

+67
-15
lines changed

lib/concurrent/delay.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ class Delay
4141
include Obligation
4242
include ExecutorOptions
4343

44+
# NOTE: Because the global thread pools are lazy-loaded with these objects
45+
# there is a performance hit every time we post a new task to one of these
46+
# thread pools. Subsequently it is critical that `Delay` perform as fast
47+
# as possible post-completion. This class has been highly optimized using
48+
# the benchmark script `examples/lazy_and_delay.rb`. Do NOT attempt to
49+
# DRY-up this class or perform other refactoring with running the
50+
# benchmarks and ensuring that performance is not negatively impacted.
51+
4452
# Create a new `Delay` in the `:pending` state.
4553
#
4654
# @yield the delayed operation to perform
@@ -153,6 +161,8 @@ def reconfigure(&block)
153161

154162
# @!visibility private
155163
def execute_task_once # :nodoc:
164+
# this function has been optimized for performance and
165+
# should not be modified without running new benchmarks
156166
mutex.lock
157167
execute = @computing = true unless @computing
158168
task = @task

lib/concurrent/obligation.rb

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,62 +10,96 @@ module Obligation
1010
include Dereferenceable
1111

1212
# Has the obligation been fulfilled?
13+
#
1314
# @return [Boolean]
1415
def fulfilled?
1516
state == :fulfilled
1617
end
1718
alias_method :realized?, :fulfilled?
1819

1920
# Has the obligation been rejected?
21+
#
2022
# @return [Boolean]
2123
def rejected?
2224
state == :rejected
2325
end
2426

2527
# Is obligation completion still pending?
28+
#
2629
# @return [Boolean]
2730
def pending?
2831
state == :pending
2932
end
3033

3134
# Is the obligation still unscheduled?
35+
#
3236
# @return [Boolean]
3337
def unscheduled?
3438
state == :unscheduled
3539
end
3640

37-
def completed?
41+
# Has the obligation completed processing?
42+
#
43+
# @return [Boolean]
44+
def complete?
3845
[:fulfilled, :rejected].include? state
3946
end
4047

48+
# Has the obligation completed processing?
49+
#
50+
# @return [Boolean]
51+
#
52+
# @deprecated
53+
def completed?
54+
warn '[DEPRECATED] Use #complete? instead'
55+
complete?
56+
end
57+
58+
# Is the obligation still awaiting completion of processing?
59+
#
60+
# @return [Boolean]
4161
def incomplete?
4262
[:unscheduled, :pending].include? state
4363
end
4464

65+
# The current value of the obligation. Will be `nil` while the state is
66+
# pending or the operation has been rejected.
67+
#
68+
# @param [Numeric] timeout the maximum time in seconds to wait.
4569
# @return [Object] see Dereferenceable#deref
4670
def value(timeout = nil)
4771
wait timeout
4872
deref
4973
end
5074

51-
# wait until Obligation is #complete?
52-
# @param [Numeric] timeout the maximum time in second to wait.
75+
# Wait until obligation is complete or the timeout has been reached.
76+
#
77+
# @param [Numeric] timeout the maximum time in seconds to wait.
5378
# @return [Obligation] self
5479
def wait(timeout = nil)
5580
event.wait(timeout) if timeout != 0 && incomplete?
5681
self
5782
end
5883

59-
# wait until Obligation is #complete?
60-
# @param [Numeric] timeout the maximum time in second to wait.
84+
# Wait until obligation is complete or the timeout is reached. Will re-raise
85+
# any exceptions raised during processing (but will not raise an exception
86+
# on timeout).
87+
#
88+
# @param [Numeric] timeout the maximum time in seconds to wait.
6189
# @return [Obligation] self
62-
# @raise [Exception] when #rejected? it raises #reason
63-
def no_error!(timeout = nil)
90+
# @raise [Exception] raises the reason when rejected
91+
def wait!(timeout = nil)
6492
wait(timeout).tap { raise self if rejected? }
6593
end
94+
alias_method :no_error!, :wait!
6695

67-
# @raise [Exception] when #rejected? it raises #reason
96+
# The current value of the obligation. Will be `nil` while the state is
97+
# pending or the operation has been rejected. Will re-raise any exceptions
98+
# raised during processing (but will not raise an exception on timeout).
99+
#
100+
# @param [Numeric] timeout the maximum time in seconds to wait.
68101
# @return [Object] see Dereferenceable#deref
102+
# @raise [Exception] raises the reason when rejected
69103
def value!(timeout = nil)
70104
wait(timeout)
71105
if rejected?
@@ -75,13 +109,21 @@ def value!(timeout = nil)
75109
end
76110
end
77111

112+
# The current state of the obligation.
113+
#
114+
# @return [Symbol] the current state
78115
def state
79116
mutex.lock
80117
@state
81118
ensure
82119
mutex.unlock
83120
end
84121

122+
# If an exception was raised during processing this will return the
123+
# exception object. Will return `nil` when the state is pending or if
124+
# the obligation has been successfully fulfilled.
125+
#
126+
# @return [Exception] the exception raised during processing or `nil`
85127
def reason
86128
mutex.lock
87129
@reason
@@ -134,8 +176,8 @@ def state=(value) # :nodoc:
134176
mutex.unlock
135177
end
136178

137-
# atomic compare and set operation
138-
# state is set to next_state only if current state is == expected_current
179+
# Atomic compare and set operation
180+
# State is set to `next_state` only if `current state == expected_current`.
139181
#
140182
# @param [Symbol] next_state
141183
# @param [Symbol] expected_current

spec/concurrent/actor_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ def on_message(message)
144144
envelope = subject.ask!('a')
145145
expect(envelope).to be_a_kind_of Envelope
146146
expect(envelope.message).to eq 'a'
147-
expect(envelope.ivar).to be_completed
147+
expect(envelope.ivar).to be_complete
148148
expect(envelope.ivar.value).to eq envelope
149149
expect(envelope.sender).to eq Thread.current
150150
terminate_actors subject

spec/concurrent/obligation_spec.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def initialize
2222
shared_examples :incomplete do
2323

2424
it 'should be not completed' do
25-
expect(obligation).not_to be_completed
25+
expect(obligation).not_to be_complete
2626
end
2727

2828
it 'should be incomplete' do
@@ -79,7 +79,7 @@ def initialize
7979
end
8080

8181
it 'should be completed' do
82-
expect(obligation).to be_completed
82+
expect(obligation).to be_complete
8383
end
8484

8585
it 'should be not incomplete' do
@@ -156,7 +156,7 @@ def initialize
156156
end
157157

158158
it 'should be completed' do
159-
expect(obligation).to be_completed
159+
expect(obligation).to be_complete
160160
end
161161

162162
it 'should be not incomplete' do

yardoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Subproject commit db7483b80f6efb7df9930f0031508d7e2eb6bad0
1+
Subproject commit 5aff4706f70d757c15830edd66d74759ff364eda

0 commit comments

Comments
 (0)