예제 #1
0
func cmdDaemon(c *cli.Context) {
	app := libswarm.NewServer()
	app.OnLog(func(args ...string) error {
		log.Printf("%s\n", strings.Join(args, " "))
		return nil
	})
	app.OnError(func(args ...string) error {
		Fatalf("Fatal: %v", strings.Join(args[:1], ""))
		return nil
	})
	back := backends.New()
	if len(c.Args()) == 0 {
		names, err := back.Ls()
		if err != nil {
			Fatalf("ls: %v", err)
		}
		fmt.Println(strings.Join(names, "\n"))
		return
	}
	var previousInstanceR libswarm.Receiver
	// FIXME: refactor into a Pipeline
	for idx, backendArg := range c.Args() {
		bName, bArgs, err := parseCmd(backendArg)
		if err != nil {
			Fatalf("parse: %v", err)
		}
		_, backend, err := back.Attach(bName)
		if err != nil {
			Fatalf("%s: %v\n", bName, err)
		}
		instance, err := backend.Spawn(bArgs...)
		if err != nil {
			Fatalf("spawn %s: %v\n", bName, err)
		}
		instanceR, instanceW, err := instance.Attach("")
		if err != nil {
			Fatalf("attach: %v", err)
		}
		go func(r libswarm.Receiver, w libswarm.Sender, idx int) {
			if r != nil {
				libswarm.Copy(w, r)
			}
			w.Close()
		}(previousInstanceR, instanceW, idx)
		if err := instance.Start(); err != nil {
			Fatalf("start: %v", err)
		}
		previousInstanceR = instanceR
	}
	_, err := libswarm.Copy(app, previousInstanceR)
	if err != nil {
		Fatalf("copy: %v", err)
	}
}
예제 #2
0
func (a *aggregator) attach(name string, ret libswarm.Sender) error {
	if name != "" {
		// TODO: implement this?
		return fmt.Errorf("attaching to a child is not implemented")
	}

	if _, err := ret.Send(&libswarm.Message{Verb: libswarm.Ack, Ret: a.server}); err != nil {
		return err
	}

	var copies sync.WaitGroup

	for _, b := range a.backends {
		r, _, err := b.Attach("")
		if err != nil {
			return err
		}
		copies.Add(1)
		go func() {
			log.Printf("copying output from %#v\n", b)
			libswarm.Copy(ret, r)
			log.Printf("finished output from %#v\n", b)
			copies.Done()
		}()
	}

	copies.Wait()
	return nil
}
예제 #3
0
func Task(f func(in libswarm.Receiver, out libswarm.Sender)) libswarm.Sender {
	var running bool
	var l sync.RWMutex
	inR, inW := libswarm.Pipe()
	outR, outW := libswarm.Pipe()
	obj := libswarm.NewServer()
	obj.OnVerb(libswarm.Attach, libswarm.Handler(func(msg *libswarm.Message) error {
		msg.Ret.Send(&libswarm.Message{Verb: libswarm.Ack, Ret: inW})
		fmt.Printf("copying task output from %#v to %#v\n", outR, msg.Ret)
		defer fmt.Printf("(DONE) copying task output from %#v to %#v\n", outR, msg.Ret)
		libswarm.Copy(msg.Ret, outR)
		return nil
	}))
	obj.OnVerb(libswarm.Start, libswarm.Handler(func(msg *libswarm.Message) error {
		l.RLock()
		r := running
		l.RUnlock()
		if r {
			return fmt.Errorf("already running")
		}
		l.Lock()
		go f(inR, outW)
		running = true
		l.Unlock()
		msg.Ret.Send(&libswarm.Message{Verb: libswarm.Ack})
		return nil
	}))
	return obj
}
예제 #4
0
func Simulator() libswarm.Sender {
	s := libswarm.NewServer()
	s.OnVerb(libswarm.Spawn, libswarm.Handler(func(ctx *libswarm.Message) error {
		containers := ctx.Args
		instance := utils.Task(func(in libswarm.Receiver, out libswarm.Sender) {
			libswarm.AsClient(out).Log("[simulator] starting\n")
			s := libswarm.NewServer()
			s.OnVerb(libswarm.Ls, libswarm.Handler(func(msg *libswarm.Message) error {
				libswarm.AsClient(out).Log("[simulator] generating fake list of objects...\n")
				libswarm.AsClient(msg.Ret).Set(containers...)
				return nil
			}))
			libswarm.Copy(s, in)
		})
		ctx.Ret.Send(&libswarm.Message{Verb: libswarm.Ack, Ret: instance})
		return nil
	}))
	return s
}
예제 #5
0
// Spawn will return a new instance as the Ret channel of the message sent back
func (dbg *debug) spawn(msg *libswarm.Message) (err error) {
	// By sending back a task, libswarm will run the function with the in and out arguments
	// set to the services present before and after this one in the pipeline.
	instance := utils.Task(func(in libswarm.Receiver, out libswarm.Sender) {
		// Setup our channels
		dbg.out = out

		// Set up the debug interceptor
		dbg.service.Catchall(libswarm.Handler(dbg.catchall))

		// Copy everything from the receiver to our service. By copying like this in the task
		// we can use the catchall handler instead of handling the message here.
		libswarm.Copy(dbg.service, in)
	})

	// Inform the system of our new instance
	msg.Ret.Send(&libswarm.Message{
		Verb: libswarm.Ack,
		Ret:  instance,
	})

	return
}