func Forward(ctx context.Context, options *Options) (err error) {
	log.Debug("construct forwarding pipeline")
	defer func() {
		if err != nil {
			cleanupClients(options)
		}
	}()
	runnables := make([]runnable.Runnable, len(options.Hosts))
	optSlice := make([][]string, len(options.Hosts))
	for i, host := range options.Hosts {
		switch host.Transport {
		case GRPC:
			{
				uri := fmt.Sprintf("dns:///%v:%v", host.Host, host.Port)
				var fn *grpc.Client
				if cli, ok := clients[uri]; ok {
					fn = cli
				} else {
					creds, err := getTransportCredentials(host.Host)
					if err != nil {
						log.Errorf("failed to get credentials for %v: %v", host.Host, err)
						return err
					}
					rr := balancer.Get("round_robin")
					fn, err = grpc.NewClientWithContext(ctx, uri, creds, g.WithBalancerBuilder(rr))
					if err != nil {
						log.Errorf("failed to get gRPC client for %v: %v", host.Host, err)
						return err
					}
					clients[uri] = fn
				}
				runnables[i] = fn
				optSlice[i] = host.CallOptions
				log.Debugf("added grpc://%v to the pipeline", uri)
			}
		case HTTP:
			{
				fn := NewHTTPRunnable(fmt.Sprintf("http://%v:%v", host.Host, host.Port))
				runnables[i] = fn
				optSlice[i] = host.CallOptions
			}
		default:
			{
				return errors.New("transport not implemented")
			}
		}
	}
	cmd := chain.New(runnables...)
	log.Debug("finished constructing pipeline, kickoff...")
	return cmd.Run(ctx, optSlice, options.Input, options.Output)
}
Forward forwards a function call
package forwarder
import (
	"context"
	"crypto/tls"
	"crypto/x509"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	log "github.com/Sirupsen/logrus"
	"github.com/trusch/btrfaas/frunner/grpc"
	"github.com/trusch/btrfaas/frunner/runnable"
	"github.com/trusch/btrfaas/frunner/runnable/chain"
	g "google.golang.org/grpc"
	"google.golang.org/grpc/balancer"
	_ "google.golang.org/grpc/balancer/roundrobin"
	"google.golang.org/grpc/credentials"
)
type Options struct {
	Hosts  []*HostConfig
	Input  io.Reader
	Output io.Writer
}
type HostConfig struct {
	Transport   TransportProtocol
	Host        string
	Port        uint16
	CallOptions []string
}
type TransportProtocol int
const (
	GRPC TransportProtocol = iota
	HTTP
)
var clients = make(map[string]*grpc.Client)