docs/backends/backends.go

87 lines
2.3 KiB
Go

package backends
import (
"io"
"fmt"
"github.com/docker/beam"
beamutils "github.com/docker/beam/utils"
"strings"
"sync"
"time"
)
// New returns a new engine, with all backends
// registered but not activated.
// To activate a backend, call a job on the resulting
// engine, named after the desired backend.
//
// Example: `New().Job("debug").Run()`
func New() beam.Sender {
backends := beamutils.NewHub()
backends.RegisterName("cd", func(msg *beam.Message, in beam.Receiver, out beam.Sender, next beam.Sender) (bool, error) {
return false, fmt.Errorf("no such backend: %s\n", strings.Join(msg.Args, " "))
})
backends.RegisterName("cd", func(msg *beam.Message, in beam.Receiver, out beam.Sender, next beam.Sender) (bool, error) {
if len(msg.Args) > 0 && msg.Args[0] == "debug" {
debugr, debugw, err := out.Send(&beam.Message{Name: "register"}, beam.R|beam.W)
if err != nil {
return false, err
}
go func() {
for {
msg, msgr, msgw, err := debugr.Receive(beam.R | beam.W)
if err == io.EOF {
return
}
if err != nil {
return
}
fmt.Printf("[DEBUG] %s %s\n", msg.Name, strings.Join(msg.Args, " "))
// FIXME: goroutine?
Splice(debugw, msg, msgr, msgw)
}
}()
return false, nil
}
return true, nil
})
backends.RegisterName("fakeclient", func(msg *beam.Message, in beam.Receiver, out beam.Sender, next beam.Sender) (bool, error) {
backends.RegisterTask(func(r beam.Receiver, w beam.Sender) error {
for {
time.Sleep(1 * time.Second)
_, _, err := w.Send(&beam.Message{Name: "log", Args: []string{"fake client reporting for duty"}}, 0)
if err != nil {
return err
}
containersR, _, err := w.Send(&beam.Message{Name: "containers"}, beam.R)
if err != nil {
return err
}
go beamutils.Copy(beam.NopSender{}, containersR)
}
})
return true, nil
})
return backends
}
func Splice(dst beam.Sender, msg *beam.Message, r beam.Receiver, w beam.Sender) error {
dstR, dstW, err := dst.Send(msg, beam.R|beam.W)
if err != nil {
return err
}
defer dstW.Close()
var tasks sync.WaitGroup
_copy := func(dst beam.Sender, src beam.Receiver) {
tasks.Add(1)
go func() {
defer tasks.Done()
beamutils.Copy(dst, src)
}()
}
_copy(dstW, r)
_copy(w, dstR)
tasks.Wait()
return nil
}