Skip to content

Commit 360c774

Browse files
committed
Add Delay#reconfigure method
allows to replace the block evaluating to the value with new one only if a delay is still incomplete?
1 parent 2160db1 commit 360c774

File tree

2 files changed

+41
-10
lines changed

2 files changed

+41
-10
lines changed

lib/concurrent/delay.rb

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require 'thread'
2+
require 'concurrent/obligation'
23

34
module Concurrent
45

@@ -48,7 +49,7 @@ def initialize(opts = {}, &block)
4849

4950
init_obligation
5051
@state = :pending
51-
@task = block
52+
@task = block
5253
set_deref_options(opts)
5354
end
5455

@@ -78,18 +79,34 @@ def value
7879
mutex.unlock
7980
end
8081

82+
# reconfigures the block returning the value if still #incomplete?
83+
# @yield the delayed operation to perform
84+
# @returns [true, false] if success
85+
def reconfigure(&block)
86+
mutex.lock
87+
raise ArgumentError.new('no block given') unless block_given?
88+
if @state == :pending
89+
@task = block
90+
true
91+
else
92+
false
93+
end
94+
ensure
95+
mutex.unlock
96+
end
97+
8198
private
8299

83-
def execute_task_once
84-
if @state == :pending
85-
begin
86-
@value = @task.call
87-
@state = :fulfilled
88-
rescue => ex
89-
@reason = ex
90-
@state = :rejected
91-
end
100+
def execute_task_once
101+
if @state == :pending
102+
begin
103+
@value = @task.call
104+
@state = :fulfilled
105+
rescue => ex
106+
@reason = ex
107+
@state = :rejected
92108
end
93109
end
110+
end
94111
end
95112
end

spec/concurrent/delay_spec.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,20 @@ def dereferenceable_subject(value, opts = {})
5353
end
5454
end
5555

56+
57+
context '#reconfigure' do
58+
it 'returns value of block used in reconfiguration' do
59+
Delay.new { nil }.tap { |d| d.reconfigure { true } }.value.should be_true
60+
end
61+
62+
it 'returns false when process completed?' do
63+
d = Delay.new { 1 }
64+
d.reconfigure { 2 }.should be_true
65+
d.value.should be 2
66+
d.reconfigure { 3 }.should be_false
67+
end
68+
end
69+
5670
context '#value' do
5771

5872
let(:task){ proc{ nil } }

0 commit comments

Comments
 (0)