trustmaster / goflow

Flow-based and dataflow programming library for Go (golang)
MIT License
1.6k stars 125 forks source link

v1 Design proposal #49

Open trustmaster opened 5 years ago

trustmaster commented 5 years ago

7 years after starting this project, after writing and maintaining some FBP apps in production, after collecting feedback on this project (#48), it's time to propose the design for v1.0 of GoFlow library. The main goal is to make the library itself less complicated and make effort from zero to a real app minimal.

Steps

Components

First, to reduce complexity, the following features are removed:

It is still be possible to implement all that functionality in the components themselves in pure Go code.

Structure

The structure definition of the components will be simplified:

type ExampleComponent struct {
    Foo <-chan int  // inport
    Bar chan<- int  // outport
}

Process

Reactive port handlers are removed in favour of more generic Process() function, defining the whole behaviour of the component.

So, long-running ("looper") components can be implemented like this:

func (c *ExampleComponent) Process() {
    for f := range c.Foo {
        // Do something
        c.Bar <- data
    }
}

A short-running ("non-looper") process would just return immediately after reading the input:

func (c *ExampleComponent) Process() {
    f := <-c.Foo
    // Do something
    c.Bar <- data
}

Graphs

API

The API for working with Graphs remains the same as before.

Underlying code is to be refactored, but no dramatic changes are expected. Yes, it will still use reflection to connect nodes in the network - because that brings a lot of convenience and run-time capabilities and only affects performance upon application start.

FBP files

One of the goals for v1 is to use FBP DSL as primary way to define graphs. So, instead of many lines of Go code, you could write something like this:

INPORT=Server.Port:Port
OUTPORT=Logger.Output:Log

Server(http/Server) Req -> Req Handler(app/Handler) Err -> Logger(log/Logger)
Middleware(http/Middleware) Funcs -> Middleware Server

Support for FBP files is built into runtime, so it can be called like:

n, err := flow.LoadGraph("app/main.fbp")

port := make(chan int)
n.SetInPort("Port", port)

wait := flow.Run(n)

port <- 8000

Runtime

For v1.0, the runtime should be powerful enough just to load and run .fbp graphs.

Support for FBP Protocol and Flowhub is to be added later. Though, existing work such as compatibility with JSON graph format will be kept to make future integration easier.