func LinealPipeline(nodes ...*Node) Pipeliner {
	p := &SimplePipeline{}
	p.nodes = make(map[string]*Node)
	for i := 1; i < len(nodes); i++ {
		prev := nodes[i-1]
		curr := nodes[i]
		prev.Chain(curr)
		p.nodes[prev.ID()] = prev
		p.nodes[curr.ID()] = curr
	}
	return p
}
LinealPipeline creates a Pipeliner
Nodes in "nodes" are chained in a slingle branch Pipeline
Node(0)->Node(1)->Node(2)->....Node(n)
package selina
import (
	"context"
	"fmt"
	"io"
	"strconv"
	"golang.org/x/sync/errgroup"
)
type Pipeliner interface {
	Run(context.Context) error
	Stats() map[string]Stats
	Nodes() []*Node
}
type SimplePipeline struct {
	nodes map[string]*Node
}
func (p *SimplePipeline) Run(ctx context.Context) error {
	g, ctx := errgroup.WithContext(ctx)
	for _, n := range p.nodes {
		node := n
		g.Go(func() error {
			return node.Start(ctx)
		})
	}
	return g.Wait()
}
func (p *SimplePipeline) Stats() map[string]Stats {
	ret := make(map[string]Stats)
	for _, n := range p.nodes {
		ret[n.ID()] = n.Stats()
	}
	return ret
}
func (p *SimplePipeline) Nodes() []*Node {
	ret := make([]*Node, 0, len(p.nodes))
	for _, v := range p.nodes {
		ret = append(ret, v)
	}
	return ret
}