Skip to content

Commit

Permalink
Support custom forkers
Browse files Browse the repository at this point in the history
  • Loading branch information
Larry Diehl committed Aug 29, 2009
1 parent f4ce4f2 commit 5199701
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 5 deletions.
29 changes: 25 additions & 4 deletions README.textile
Expand Up @@ -68,6 +68,8 @@ Dataflow.local do |x, y, z|
Thread.new { Dataflow.unify x, 1 }
z #=> 6
end

# Note that a gobal Dataflow.declare is not supported
</pre>

<pre>
Expand Down Expand Up @@ -150,10 +152,6 @@ local do |x|
end
x #=> 1337
end

# NOTE: flow is used internally by need_later. This means that you
# could override flow to do other things like use a threadpool,
# and this would also affect need_later.
</pre>

<pre>
Expand Down Expand Up @@ -183,6 +181,29 @@ local do |queue, first, second|
end
</pre>

h1. Debugging

If you are having trouble and need to debug dataflow variables, simply call #inspect.

If the variable has already been bound, it call inspect on its bound value like normal.However, if the variable is not bound yet then you will get a special string that contains the proxies #__id__ that you can use to track down which proxy objects are being passed around to which parts of your program:
<pre>
local do |my_var|
my_var.inspect # => #<Dataflow::Variable:2637860 unbound>
end
</pre>

h1. Fork method customization

By default both #flow and #need_later use Thread.fork as their fork method. Youc an access the fork method via Dataflow.forker.

If you would like to use a custom forker, simple set it to a method that accepts and calls a block (for an example of a synchronous forker, see spec/forker_spec.rb):
<pre>
Dataflow.forker = MyClass.method(:fork_with_threadpool)
</pre>

Also note that #flow is used interally by #need_later, in case you want to override that specifically.


h1. Ports using Dataflow

Ports are an extension of the declarative concurrent model to support nondeterministic behavior. They accomplish this through the use of a single state variable. Ports are also inspired by the Oz language.
Expand Down
6 changes: 5 additions & 1 deletion dataflow.rb
Expand Up @@ -2,6 +2,10 @@

module Dataflow
VERSION = "0.3.0"
class << self
attr_accessor :forker
end
self.forker = Thread.method(:fork)

def self.included(cls)
class << cls
Expand Down Expand Up @@ -36,7 +40,7 @@ def barrier(*variables)
end

def flow(output=nil, &block)
Thread.new do
Dataflow.forker.call do
result = block.call
unify output, result if output
end
Expand Down
28 changes: 28 additions & 0 deletions spec/forker_spec.rb
@@ -0,0 +1,28 @@
require "#{File.dirname(__FILE__)}/spec_helper"

describe 'Setting a customer forker' do
before(:all) do
@original_forker = Dataflow.forker
Dataflow.forker = Class.new do
def self.synchronous_forker(&block)
block.call
end
end.method(:synchronous_forker)
end

after(:all) do
Dataflow.forker = @original_forker
end

it 'uses the custom forker in #flow' do
local do |my_var|
flow(my_var) { 1337 }
my_var.should == 1337
end
end

it 'uses the custom forker in #need_later' do
my_var = need_later { 1337 }
my_var.should == 1337
end
end

0 comments on commit 5199701

Please sign in to comment.