Example #1
0
func TestSendRet(t *testing.T) {
	r, w := beam.Pipe()
	defer r.Close()
	defer w.Close()
	q := NewQueue(w, 1)
	defer q.Close()
	ret, err := q.Send(&beam.Message{Verb: beam.Log, Args: []string{"ping"}, Ret: beam.RetPipe})
	if err != nil {
		t.Fatal(err)
	}
	go func() {
		ping, err := r.Receive(beam.Ret)
		if err != nil {
			t.Fatal(err)
		}
		if _, err := ping.Ret.Send(&beam.Message{Verb: beam.Log, Args: []string{"pong"}}); err != nil {
			t.Fatal(err)
		}
	}()
	pong, err := ret.Receive(0)
	if err != nil {
		t.Fatal(err)
	}
	if pong.Verb != beam.Log {
		t.Fatal(err)
	}
}
Example #2
0
func NewQueue(dst beam.Sender, size int) *Queue {
	r, w := beam.Pipe()
	q := &Queue{
		PipeSender: w,
		dst:        dst,
		ch:         make(chan *beam.Message, size),
	}
	go func() {
		defer close(q.ch)
		for {
			msg, err := r.Receive(beam.Ret)
			if err != nil {
				r.Close()
				return
			}
			q.ch <- msg
		}
	}()
	go func() {
		for msg := range q.ch {
			_, err := dst.Send(msg)
			if err != nil {
				r.Close()
				return
			}
		}
	}()
	return q
}
Example #3
0
func TestStackWithPipe(t *testing.T) {
	r, w := beam.Pipe()
	defer r.Close()
	defer w.Close()
	s := NewStackSender()
	s.Add(w)
	testutils.Timeout(t, func() {
		go func() {
			msg, err := r.Receive(0)
			if err != nil {
				t.Fatal(err)
			}
			if msg.Verb != beam.Log {
				t.Fatalf("%#v", msg)
			}
			if strings.Join(msg.Args, " ") != "wonderful world" {
				t.Fatalf("%#v", msg)
			}
		}()
		_, err := s.Send(&beam.Message{Verb: beam.Log, Args: []string{"wonderful", "world"}})
		if err != nil {
			t.Fatal(err)
		}
	})
}
Example #4
0
// Misbehaving backends must be removed
func TestStackAddBad(t *testing.T) {
	s := NewStackSender()
	buf := Buffer{}
	s.Add(&buf)
	r, w := beam.Pipe()
	s.Add(w)
	if s.Len() != 2 {
		t.Fatalf("%#v", s)
	}
	r.Close()
	if _, err := s.Send(&beam.Message{Verb: beam.Log, Args: []string{"for the buffer"}}); err != nil {
		t.Fatal(err)
	}
	if s.Len() != 1 {
		t.Fatalf("%#v")
	}
	if len(buf) != 1 {
		t.Fatalf("%#v", buf)
	}
	if buf[0].Args[0] != "for the buffer" {
		t.Fatalf("%#v", buf)
	}
}
Example #5
0
func Exec() beam.Sender {
	e := beam.NewServer()
	e.OnSpawn(beam.Handler(func(msg *beam.Message) error {
		if len(msg.Args) < 1 {
			return fmt.Errorf("usage: SPAWN exec|... <config>")
		}
		if msg.Args[0] != "exec" {
			return fmt.Errorf("invalid command: %s", msg.Args[0])
		}
		var config struct {
			Path string
			Args []string
		}
		if err := json.Unmarshal([]byte(msg.Args[1]), &config); err != nil {
			config.Path = msg.Args[1]
			config.Args = msg.Args[2:]
		}
		cmd := &command{
			Cmd:    exec.Command(config.Path, config.Args...),
			Server: beam.NewServer(),
		}
		cmd.OnAttach(beam.Handler(func(msg *beam.Message) error {
			stdout, err := cmd.StdoutPipe()
			if err != nil {
				return err
			}
			stdin, err := cmd.StdinPipe()
			if err != nil {
				return err
			}
			inR, inW := beam.Pipe()
			if _, err := msg.Ret.Send(&beam.Message{Verb: beam.Ack, Ret: inW}); err != nil {
				return err
			}
			out := beam.Obj(msg.Ret)
			go func() {
				defer stdin.Close()
				for {
					msg, err := inR.Receive(0)
					if err != nil {
						return
					}
					if msg.Verb == beam.Log && len(msg.Args) > 0 {
						fmt.Fprintf(stdin, "%s\n", strings.TrimRight(msg.Args[0], "\r\n"))
					}
				}
			}()
			cmd.tasks.Add(1)
			go func() {
				defer cmd.tasks.Done()
				scanner := bufio.NewScanner(stdout)
				for scanner.Scan() {
					if scanner.Err() != io.EOF && scanner.Err() != nil {
						return
					}
					if err := out.Log(scanner.Text()); err != nil {
						out.Error("%v", err)
						return
					}
				}
			}()
			cmd.tasks.Wait()
			return nil
		}))
		cmd.OnStart(beam.Handler(func(msg *beam.Message) error {
			cmd.tasks.Add(1)
			if err := cmd.Cmd.Start(); err != nil {
				return err
			}
			go func() {
				defer cmd.tasks.Done()
				if err := cmd.Cmd.Wait(); err != nil {
					beam.Obj(msg.Ret).Log("%s exited status=%v", cmd.Cmd.Path, err)
				}
			}()
			msg.Ret.Send(&beam.Message{Verb: beam.Ack})
			return nil
		}))
		if _, err := msg.Ret.Send(&beam.Message{Verb: beam.Ack, Ret: cmd}); err != nil {
			return err
		}
		return nil
	}))
	return e
}