Idea: Pipe/Chain/Graph

23 views
Skip to first unread message

Steve Wagner

unread,
May 12, 2009, 11:47:07 AM5/12/09
to retla...@googlegroups.com
Hi, thank for that nice library. While looking this video about the
Microsoft Agents Library, i thought this would also be nice to have in
.Net. So here is a simple example implementation.

There are a lot of querstion, in example should each chain get its own
fiber or what is the best name for it.

So what do you think?

Steve

--------------------------

private static void Main()
{
var fiber1 = new ThreadFiber();
fiber1.Start();

var fiber2 = new ThreadFiber();
fiber2.Start();

var fiberChain1 = new FiberChain<string>( fiber1 );
var fiberChain2 = new FiberChain<int>( fiber2 );
var transform = new TransformChain<string, int>( s => int.Parse( s ) );
var tee = new TeeChain<int>();
var call1 = new ActionChain<int>( i =>
{
Thread.Sleep( 1000 );
Console.WriteLine( "call1 " + i );
} );
var call2 = new ActionChain<int>( i => Console.WriteLine( "call2 " +
i ) );

fiberChain1.LinkTarget( transform );
transform.LinkTarget( tee );
tee.LinkTarget( fiberChain2 );
fiberChain2.LinkTarget( call1 );
tee.LinkTarget( call2 );

fiberChain1.Send( "10" );

Console.ReadLine();
}

public class ActionChain<T> : IChain<T>
{
private readonly Action<T> _action;

public ActionChain( Action<T> action )
{
_action = action;
}

public void Send( T item )
{
_action( item );
}
}

public class FiberChain<T> : IChain<T>
{
private readonly IFiber _fiber;
private IChain<T> _target;

public FiberChain( IFiber fiber )
{
_fiber = fiber;
}

public void Send( T item )
{
_fiber.Enqueue( () => _target.Send( item ) );
}

public void LinkTarget( IChain<T> chain )
{
_target = chain;
}
}

public interface IChain<T>
{
void Send( T item );
}

public class TeeChain<T> : IChain<T>
{
private readonly IList<IChain<T>> _tee = new List<IChain<T>>();

public void Send( T item )
{
foreach( var tee in _tee )
tee.Send( item );
}

public void LinkTarget( IChain<T> chain )
{
_tee.Add( chain );
}
}

public class TransformChain<TIn, TOut> : IChain<TIn>
{
private readonly Func<TIn, TOut> _transform;
private IChain<TOut> _target;

public TransformChain( Func<TIn, TOut> transform )
{
_transform = transform;
}

public void Send( TIn item )
{
var result = _transform( item );

_target.Send( result );
}

public void LinkTarget( IChain<TOut> chain )
{
_target = chain;
}
}


Mike Rettig

unread,
May 14, 2009, 9:41:48 PM5/14/09
to retla...@googlegroups.com
Interesting idea. It has the beginnings of something like apache camel. 

Have you looked at camel?

I think your idea could be extended into a fluent interface for defining asynchronous workflows. 

Something like this:

var builder = new WorkflowBuilder();
 
var workflow = builder.transform<int,string>( s => int.Parse( s ))
                               .tee( n => Console.WriteLine("1 " + n))
                               .tee( n => Console.WriteLing("2 " + n))
                               .build();
workflow.publish("10");

This is very similar to your idea but with a fluent api and defaulting to pooled fibers.  This would setup a sequential workflow where each step is executed asynchronously.

Mike  
Reply all
Reply to author
Forward
0 new messages