Skip to content

dkoontz/NTransit

Repository files navigation

NTransit

What is Flow Based Programming (FBP)?

Briefly put, Flow Based Programming is an architectural pattern by which you think of your program as being comprised of independently executing processes that communicate with each other over well defined connections between output pots and input ports. FBP networks are generally drawn out in an editor or described textually as the connections between the various components' ports. When the network is executed, the components that are declared are instantiated and become the running processes of the system. A process is an instance of a component. FBP is different from many "dataflow" style systems in that the only thing that moves between processes is an "Information Packet" or IP. This simple abstraction allows for the authoring of components that know nothing about the actual data of an IP but can nonetheless operate on the packet in some fashion (batching up several packets to be sent at once, routing it based on metadata attached to the packet, etc.). For those wanting to know more I highly suggest reading the book "Flow Based Programming" by J Paul Morrison the originator of the technique. Listed below is a free version of the 1st edition and the second edition, updated in 2011 and available on Amazon.

NTransit at 30,000 feet

NTransit is still very early on and I would not recommend anyone using it for anything serious. A few test applications are being built with it to shake out an major problems and get the various schedulers built out but outside of the problem domains those applications are exploring the component library and to a degree the capabilities are not fully built out.

NTransit is a FBP runtime for C# 3.5 (.NET and Mono equivalents) and above. NTransit aims to be usable in a variety of situations such as in desktop applications, server-side, and on mobile devices. To this end, NTransit does not make any assumptions about how your processes are scheduled, instead leaving that up to a pluggable scheduler which can be multi-threaded, single threaded, or some combination of the two, (for example using a thread pool).

NTransit uses an event style model for notifying a component of incoming packets. Ports are declared as attributes on the class and accessed through the InPorts and OutPorts Dictionaries. Input ports have three event handlers: Receive, SequenceStart, SequenceEnd. There are also four event methods for the component as a whole:

InPorts["MyInputPort"].Receive = data => // process packet
InPorts["MyInputPort"].SequenceStart = data => // process start of sequence, this includes a unique sequence id
InPorts["MyInputPort"].SequenceEnd = data => // process end of sequence, this includes the same id as the sequence start

public abstract void Setup();
protected virtual void Start();
protected virtual bool Update();
protected virtual void End();

The component can choose to accept the packet or decline it which leaves the packet in the incoming port's connection. Here is an example component that receives an IP on the In port, gets its content as a string, adds an <h1> around the string, and then forwards the IP to the Out port.

[InputPort("In")]
[OutputPort("Out")]
public class AddHeaderTag : Component {
    public MyComponent(string name) : base(name) { }

	public override void Setup() {
        InPorts["In"].Receive = data => {
            ip = data.Accept();
            var value = ip.ContentAs<string>();
            ip.Content = string.Format("<h1>{0}</h1>", value);
        }
        Send("Out", ip);
    }
}

A slightly more complex version might be to allow the component to be told what tag to wrap around the content via another port.

[InputPort("Tag")]
[InputPort("In")]
[OutputPort("Out")]
public class AddHeaderTag : Component {
    string tag;

    public MyComponent(string name) : base(name) { }

	public override void Setup() {
        InPorts["Tag"].Receive = data => tag = data.Accept().ContentAs<string>();
        InPorts["In"].Receive = data => {
            ip = data.Accept();
            var value = ip.ContentAs<string>();
            ip.Content = string.Format("<{0}>{1}</{0}>", tag, value);
        }
        Send("Out", ip);
    }
}

Networks can be created via code or by a string containing a compact representation of a network. Currently this is a format unique to NTransit but hopefully soon there will be some standardization of a .fbp format (and also a JSON format) that can then be adopted. The current format uses the following:

'My literal string data' -> NameOfProcess(TypeOfComponent).InputPortName
NameOfProcess.OutputPortName -> OtherProcess(DifferentComponentType).InputPortName

Types are only declared the first time they are encountered, so the second use of NameOfProcess does not need the parentheses and type declaration. Literal types that are supported are

  • int
  • float
  • string
  • bool

Example projects

Related projects

About

A Flow Based Programming runtime for C#

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages