add fork future primitive
This commit is contained in:
38
app/lib/fork_future.rb
Normal file
38
app/lib/fork_future.rb
Normal file
@@ -0,0 +1,38 @@
|
||||
class ForkFuture
|
||||
def initialize(&block)
|
||||
read, write = ::IO.pipe
|
||||
@read = read
|
||||
pid = ::Process.fork do
|
||||
start = Time.now
|
||||
read.close
|
||||
result = block.call
|
||||
duration = Time.now - start
|
||||
::Marshal.dump({
|
||||
duration: duration,
|
||||
result: result,
|
||||
}, write)
|
||||
::Process.exit!(true)
|
||||
end
|
||||
write.close
|
||||
end
|
||||
|
||||
def join
|
||||
wait!
|
||||
@result[:result]
|
||||
end
|
||||
|
||||
def duration
|
||||
wait!
|
||||
@result[:duration]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def wait!
|
||||
@result ||= begin
|
||||
result_buffer = @read.read
|
||||
@read.close
|
||||
::Marshal.load(result_buffer)
|
||||
end
|
||||
end
|
||||
end
|
||||
18
test/lib/fork_future_test.rb
Normal file
18
test/lib/fork_future_test.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
require "test_helper"
|
||||
|
||||
class ForkFutureTest < ActiveSupport::TestCase
|
||||
def test_works
|
||||
captured = "foo"
|
||||
future1 = ForkFuture.new do
|
||||
captured + "bar"
|
||||
end
|
||||
future2 = ForkFuture.new do
|
||||
captured + "baz"
|
||||
end
|
||||
|
||||
assert_equal "foobar", future1.join
|
||||
assert_equal "foobaz", future2.join
|
||||
assert 0.0 < future1.duration
|
||||
assert 0.0 < future2.duration
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user