Ejemplo n.º 1
0
func NewLocalRepository() ThingeyRepository {
	receiver, remoteSender := libchan.Pipe()
	remoteReceiver, sender := libchan.Pipe()
	senderFunc := func() (libchan.Sender, error) {
		return sender, nil
	}
	repo := NewThingeyRepository(senderFunc, receiver, remoteSender)
	adapter := NewThingeyAdapter()
	go func() {
		for {
			adapter.Listen(remoteReceiver)
		}
	}()
	return repo
}
Ejemplo n.º 2
0
func TapClient(client net.Conn, name string, stderr bool) error {
	provider, err := spdy.NewSpdyStreamProvider(client, false)
	if err != nil {
		return err
	}

	transport := spdy.NewTransport(provider)
	sender, err := transport.NewSendChannel()
	if err != nil {
		return err
	}
	defer sender.Close()

	remoteDone, done := libchan.Pipe()
	errPipe, remoteErrPipe := libchan.Pipe()

	sm := tapStreamMessage{
		Done:   remoteDone,
		Err:    remoteErrPipe,
		Name:   name,
		Stdout: !stderr,
		W:      os.Stdout,
	}

	if err := sender.Send(&sm); err != nil {
		return err
	}

	signalChan := make(chan os.Signal)
	signal.Notify(signalChan, os.Interrupt, os.Kill)
	go func() {
		<-signalChan
		if err := done.Close(); err != nil {
			logrus.Errorf("Error closing done channel")
		}
	}()

	var em errStreamMessage
	if err := errPipe.Receive(&em); err != nil && err != io.EOF {
		return err
	}

	if em.Message != "" {
		return fmt.Errorf("remote error: %s", em.Message)
	}

	return nil
}
Ejemplo n.º 3
0
func SpawnLocalPipeBench(b *testing.B, sender BenchMessageSender, receiver BenchMessageReceiver) {
	endClient := make(chan bool)
	endServer := make(chan bool)

	receiver1, sender1 := libchan.Pipe()

	go BenchClient(b, endClient, sender1, sender, b.N)
	go BenchServer(b, endServer, receiver1, receiver, b.N)

	timeout := time.After(time.Duration(b.N+1) * 50 * time.Millisecond)

	for endClient != nil || endServer != nil {
		select {
		case <-endClient:
			if b.Failed() {
				b.Fatal("Client failed")
			}
			endClient = nil
		case <-endServer:
			if b.Failed() {
				b.Fatal("Server failed")
			}
			endServer = nil
		case <-timeout:
			if DumpStackOnTimeout {
				pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
			}
			b.Fatal("Timeout")
		}
	}
}
Ejemplo n.º 4
0
func TestChannelAbstraction(t *testing.T) {
	client := func(t *testing.T, sender libchan.Sender, s libchan.Transport) {
		recv, send := libchan.Pipe()

		m1 := &AbstractionMessage{
			Message: "irrelevant content",
			Channel: recv,
		}

		sendErr := sender.Send(m1)
		if sendErr != nil {
			t.Fatalf("Error sending channel: %s", sendErr)
		}

		closeErr := send.Close()
		if closeErr != nil {
			t.Fatalf("Error closing sender: %s", closeErr)
		}
	}
	server := func(t *testing.T, receiver libchan.Receiver, s libchan.Transport) {
		m1 := &AbstractionMessage{}
		recvErr := receiver.Receive(m1)
		if recvErr != nil {
			t.Fatalf("Error receiving message: %s", recvErr)
		}

		if expected := "irrelevant content"; m1.Message != expected {
			t.Fatalf("Unexpected message value:\n\tExpected: %s\n\tActual: %s", expected, m1.Message)
		}
	}
	SpawnClientServerTest(t, ClientSendWrapper(client), ServerReceiveWrapper(server))
}
Ejemplo n.º 5
0
func (gc *GearConn) RFSubscribe(start int64) (<-chan RFMessage, error) {
	subRecv, subSend := libchan.Pipe()
	c := make(chan RFMessage, 0)

	req := Request{
		RFS: &RFSubRequest{StartAt: start, Match: RFMessage{}, Messages: subSend},
	}

	err := gc.doRequest(&req)
	if err != nil {
		subSend.Close()
		close(c)
		return nil, err
	}

	go func() {
		for {
			var m RFMessage
			err := subRecv.Receive(&m)
			if err != nil {
				log.Printf("Error receiving RF message: %s", err.Error())
				close(c)
				return
			}
			c <- m
		}
	}()

	return c, nil
}
Ejemplo n.º 6
0
func (gc *GearConn) doRequest(req *Request) error {
	replyRecv, replySend := libchan.Pipe()
	req.Reply = replySend

	// send the request
	err := gc.mainChan.Send(req)
	if err != nil {
		replySend.Close()
		return err
	}

	// wait for a reply
	var r Reply
	err = replyRecv.Receive(&r)
	if err != nil {
		return err
	}
	switch r.Code {
	case CodeOK:
		return nil
	case CodeClientError:
		return fmt.Errorf("client error: %s", r.Error)
	case CodeServerError:
		return fmt.Errorf("server error: %s", r.Error)
	case CodeAckTimeout:
		return AckTimeoutError
	default:
		return fmt.Errorf("unknown error type: %s", r.Error)
	}
}
Ejemplo n.º 7
0
func doEcho(sender libchan.Sender, timeout time.Duration) error {
	txt := "Hello world!"
	replyRecv, replySend := libchan.Pipe()

	req := Request{ER: (*EchoRequest)(&txt), Reply: replySend}

	err := sender.Send(req)
	if err != nil {
		replySend.Close()
		return err
	}

	var reply Reply
	err = replyRecv.Receive(&reply)
	if err != nil {
		return err
	}
	if reply.Code != CodeOK {
		return fmt.Errorf("%s", reply.Error)
	}
	if string(*reply.ER) != txt {
		return fmt.Errorf("echo returned bad message: '%s'", reply.ER)
	}
	return nil
}
Ejemplo n.º 8
0
func (gc *GearConn) SensorSendData(name string, si SensorInfo) (chan<- SensorDataValue, error) {
	dataRecv, dataSend := libchan.Pipe()

	req := Request{SD: &SensorDataRequest{name, si, dataRecv}}
	err := gc.doRequest(&req)
	if err != nil {
		dataSend.Close()
		return nil, err
	}

	c := make(chan SensorDataValue, 10)

	go func() {
		for sdv := range c {
			err := dataSend.Send(sdv)
			if err != nil {
				log.Printf("Error sending SensorDataValue message: %s", err.Error())
				return
			}
		}
		dataSend.Close()
	}()

	return c, nil
}
Ejemplo n.º 9
0
func (gc *GearConn) SensorRead(name string, startAt, endAt, step int64) (
	<-chan SensorDataValue, error) {
	valuesRecv, valuesSend := libchan.Pipe()
	c := make(chan SensorDataValue, 0)

	req := Request{
		SR: &SensorReadRequest{name, startAt, endAt, step, valuesSend},
	}
	err := gc.doRequest(&req)
	if err != nil {
		valuesSend.Close()
		close(c)
		return nil, err
	}

	go func() {
		for {
			var m SensorDataValue
			err := valuesRecv.Receive(&m)
			if err != nil {
				log.Printf("Error receiving SensorData message: %s", err.Error())
				close(c)
				return
			}
			c <- m
		}
	}()

	return c, nil
}
Ejemplo n.º 10
0
func (gc *GearConn) SensorSubscribe(name string, startAt int64) (<-chan SensorDataValue, error) {
	subRecv, subSend := libchan.Pipe()
	c := make(chan SensorDataValue, 0)

	req := Request{SS: &SensorSubRequest{name, startAt, subSend}}
	err := gc.doRequest(&req)
	if err != nil {
		subSend.Close()
		close(c)
		return nil, err
	}

	go func() {
		for {
			var m SensorDataValue
			err := subRecv.Receive(&m)
			if err != nil {
				log.Printf("Error receiving SensorData message: %s", err.Error())
				close(c)
				return
			}
			c <- m
		}
	}()

	return c, nil
}
Ejemplo n.º 11
0
// GetContent retrieves the content stored at "path" as a []byte.
func (driver *StorageDriverClient) GetContent(path string) ([]byte, error) {
	if err := driver.exited(); err != nil {
		return nil, err
	}

	receiver, remoteSender := libchan.Pipe()

	params := map[string]interface{}{"Path": path}
	err := driver.sender.Send(&Request{Type: "GetContent", Parameters: params, ResponseChannel: remoteSender})
	if err != nil {
		return nil, err
	}

	response := new(ReadStreamResponse)
	err = driver.receiveResponse(receiver, response)
	if err != nil {
		return nil, err
	}

	if response.Error != nil {
		return nil, response.Error.Unwrap()
	}

	defer response.Reader.Close()
	contents, err := ioutil.ReadAll(response.Reader)
	if err != nil {
		return nil, err
	}
	return contents, nil
}
Ejemplo n.º 12
0
// PutContent stores the []byte content at a location designated by "path".
func (driver *StorageDriverClient) PutContent(path string, contents []byte) error {
	if err := driver.exited(); err != nil {
		return err
	}

	receiver, remoteSender := libchan.Pipe()

	params := map[string]interface{}{"Path": path, "Reader": ioutil.NopCloser(bytes.NewReader(contents))}
	err := driver.sender.Send(&Request{Type: "PutContent", Parameters: params, ResponseChannel: remoteSender})
	if err != nil {
		return err
	}

	response := new(WriteStreamResponse)
	err = driver.receiveResponse(receiver, response)
	if err != nil {
		return err
	}

	if response.Error != nil {
		return response.Error.Unwrap()
	}

	return nil
}
Ejemplo n.º 13
0
func NewQueue(dst libchan.Sender, size int) *Queue {
	r, w := libchan.Pipe()
	q := &Queue{
		PipeSender: w,
		dst:        dst,
		ch:         make(chan *libchan.Message, size),
	}
	go func() {
		defer close(q.ch)
		for {
			msg, err := r.Receive(libchan.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
}
Ejemplo n.º 14
0
func TestSendRet(t *testing.T) {
	r, w := libchan.Pipe()
	defer r.Close()
	defer w.Close()
	q := NewQueue(w, 1)
	defer q.Close()
	ret, err := q.Send(&libchan.Message{Data: []byte("Log"), Ret: libchan.RetPipe})
	if err != nil {
		t.Fatal(err)
	}
	go func() {
		ping, err := r.Receive(libchan.Ret)
		if err != nil {
			t.Fatal(err)
		}
		if _, err := ping.Ret.Send(&libchan.Message{Data: []byte("Log")}); err != nil {
			t.Fatal(err)
		}
	}()
	pong, err := ret.Receive(0)
	if err != nil {
		t.Fatal(err)
	}
	if string(pong.Data) != "Log" {
		t.Fatal(err)
	}
}
Ejemplo n.º 15
0
func TestChannelProxy(t *testing.T) {
	messages := []string{
		"Proxied messages",
		"Another proxied message",
		"Far less interesting message",
		"This was ALSO sent over the proxy",
	}
	client := func(t *testing.T, sender libchan.Sender) {
		for i, m := range messages {
			nestedReceiver, remoteSender := libchan.Pipe()

			message := &ProxiedMessage{
				Message: m,
				Ret:     remoteSender,
			}

			err := sender.Send(message)
			if err != nil {
				t.Fatalf("Error sending message: %s", err)
			}

			ack := &ProxyAckMessage{}
			err = nestedReceiver.Receive(ack)
			if err != nil {
				t.Fatalf("Error receiving ack: %s", err)
			}

			if ack.N != (i + 1) {
				t.Fatalf("Unexpected ack value\n\tExpected: %d\n\tActual: %d", (i + 1), ack.N)
			}

			if ack.MessageLen != len(m) {
				t.Fatalf("Unexpected ack value\n\tExpected: %d\n\tActual: %d", len(m), ack.MessageLen)
			}
		}

	}
	server := func(t *testing.T, receiver libchan.Receiver) {
		for i, m := range messages {
			message := &ProxiedMessage{}
			err := receiver.Receive(message)
			if err != nil {
				t.Fatalf("Error receiving message: %s", err)
			}

			if message.Message != m {
				t.Fatalf("Unexpected message:\n\tExpected: %s\n\tActual: %s", m, message.Message)
			}

			ack := &ProxyAckMessage{N: i + 1, MessageLen: len(message.Message)}
			err = message.Ret.Send(ack)
			if err != nil {
				t.Fatalf("Error sending ack: %s", err)
			}
		}
	}
	SpawnProxyTest(t, client, server, 4)
}
Ejemplo n.º 16
0
func main() {
	if len(os.Args) < 2 {
		usage()
	}
	var addr string
	flag.StringVar(&addr, addressFlagName, addressFlagDefaultValue, addressFlagDescription)
	flag.Parse()
	if !flag.Parsed() {
		log.Printf("%s: invalid argument(s)\n", os.Args[0])
		usage()
	}

	var client net.Conn
	var err error
	if os.Getenv("USE_TLS") != "" {
		client, err = tls.Dial("tcp", addr, &tls.Config{InsecureSkipVerify: true})
	} else {
		client, err = net.Dial("tcp", addr)
	}
	if err != nil {
		log.Fatal(err)
	}

	p, err := spdy.NewSpdyStreamProvider(client, false)
	if err != nil {
		log.Fatal(err)
	}
	transport := spdy.NewTransport(p)
	sender, err := transport.NewSendChannel()
	if err != nil {
		log.Fatal(err)
	}

	receiver, remoteSender := libchan.Pipe()

	command := &RemoteCommand{
		Cmd:        flag.Args()[0],
		Args:       flag.Args()[1:],
		Stdin:      os.Stdin,
		Stdout:     os.Stdout,
		Stderr:     os.Stderr,
		StatusChan: remoteSender,
	}

	err = sender.Send(command)
	if err != nil {
		log.Fatal(err)
	}

	response := &CommandResponse{}
	err = receiver.Receive(response)
	if err != nil {
		log.Fatal(err)
	}

	os.Exit(response.Status)
}
Ejemplo n.º 17
0
func SpawnLocalProxyBench(b *testing.B, sender BenchMessageSender, receiver BenchMessageReceiver) {
	endClient := make(chan bool)
	endServer := make(chan bool)
	endProxy1 := make(chan bool)
	endProxy2 := make(chan bool)

	receiver1, sender1, err := testPipe()
	if err != nil {
		b.Fatalf("Error creating pipe: %s", err)
	}
	receiver2, sender2 := libchan.Pipe()
	receiver3, sender3, err := testPipe()
	if err != nil {
		b.Fatalf("Error creating pipe: %s", err)
	}

	go BenchProxy(b, endProxy1, sender2, receiver1, b.N)
	go BenchProxy(b, endProxy2, sender3, receiver2, b.N)
	go BenchClient(b, endClient, sender1, sender, b.N)
	go BenchServer(b, endServer, receiver3, receiver, b.N)

	timeout := time.After(time.Duration(b.N+1) * 100 * time.Millisecond)

	for endClient != nil || endServer != nil || endProxy1 != nil || endProxy2 != nil {
		select {
		case <-endProxy1:
			if b.Failed() {
				b.Fatal("Proxy failed")
			}
			endProxy1 = nil
		case <-endProxy2:
			if b.Failed() {
				b.Fatal("Proxy failed")
			}
			endProxy2 = nil
		case <-endClient:
			if b.Failed() {
				b.Fatal("Client failed")
			}
			endClient = nil
		case <-endServer:
			if b.Failed() {
				b.Fatal("Server failed")
			}
			endServer = nil
		case <-timeout:
			if DumpStackOnTimeout {
				pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
			}
			b.Fatal("Timeout")
		}
	}
}
Ejemplo n.º 18
0
func main() {

	remote := flag.String("remote", "localhost", "Where to find that there server there")
	port := flag.String("port", "8080", "The port to listen on")
	flag.Parse()
	fmt.Println("Config: ", *remote, *port)

	client, err := net.Dial("tcp", *remote+":"+*port)
	check(err)

	p, err := spdy.NewSpdyStreamProvider(client, false)
	check(err)

	transport := spdy.NewTransport(p)
	sender, err := transport.NewSendChannel()
	check(err)

	receiver, remoteSender := libchan.Pipe()

	closeReceiver, _ := libchan.Pipe()

	command := &RemoteCommand{
		Cmd:     "attach",
		Args:    make([]string, 3),
		OutChan: remoteSender,
		Closer:  closeReceiver,
	}

	err = sender.Send(command)
	check(err)

	for {
		rLine := &RemoteLine{}
		err = receiver.Receive(rLine)
		fmt.Println(rLine.Line)
	}

}
Ejemplo n.º 19
0
func main() {
	if len(os.Args) < 2 {
		log.Fatal("usage: <command> [<arg> ]")
	}

	var client net.Conn
	var err error
	if os.Getenv("USE_TLS") != "" {
		client, err = tls.Dial("tcp", "127.0.0.1:9323", &tls.Config{InsecureSkipVerify: true})
	} else {
		client, err = net.Dial("tcp", "127.0.0.1:9323")
	}
	if err != nil {
		log.Fatal(err)
	}

	p, err := spdy.NewSpdyStreamProvider(client, false)
	if err != nil {
		log.Fatal(err)
	}
	transport := spdy.NewTransport(p)
	sender, err := transport.NewSendChannel()
	if err != nil {
		log.Fatal(err)
	}

	receiver, remoteSender := libchan.Pipe()

	command := &RemoteCommand{
		Cmd:        os.Args[1],
		Args:       os.Args[2:],
		Stdin:      os.Stdin,
		Stdout:     os.Stdout,
		Stderr:     os.Stderr,
		StatusChan: remoteSender,
	}

	err = sender.Send(command)
	if err != nil {
		log.Fatal(err)
	}

	response := &CommandResponse{}
	err = receiver.Receive(response)
	if err != nil {
		log.Fatal(err)
	}

	os.Exit(response.Status)
}
Ejemplo n.º 20
0
func NewRemoteRepository(remoteURL string) ThingeyRepository {
	receiver, remoteSender := libchan.Pipe()
	var client net.Conn
	var err error
	client, err = net.Dial("tcp", remoteURL)
	if err != nil {
		log.Fatal(err)
	}

	transport, err := spdy.NewClientTransport(client)
	if err != nil {
		log.Fatal(err)
	}
	return NewThingeyRepository(transport.NewSendChannel, receiver, remoteSender)
}
Ejemplo n.º 21
0
func Client(task *Task, proto *string, socket *string) int {
	var client net.Conn
	var err error
	if os.Getenv("USE_TLS") != "" {
		client, err = tls.Dial(*proto, *socket, &tls.Config{InsecureSkipVerify: true})
	} else {
		client, err = net.Dial(*proto, *socket)
	}
	if err != nil {
		log.Fatal(err)
	}
	transport, err := spdy.NewClientTransport(client)
	if err != nil {
		log.Fatal(err)
	}
	sender, err := transport.NewSendChannel()
	if err != nil {
		log.Fatal(err)
	}
	receiver, remoteSender := libchan.Pipe()
	//_, remoteSender := libchan.Pipe()
	command := &Command{
		Cmd:        task.Module,
		Args:       task.Args[0:],
		Stdin:      os.Stdin,
		Stdout:     os.Stdout,
		Stderr:     os.Stderr,
		StatusChan: remoteSender,
	}
	err = sender.Send(command)
	if err != nil {
		log.Fatal(err)
	}
	//sender.Close()
	response := &CommandResponse{}
	err = receiver.Receive(response)
	if err != nil {
		log.Fatal(err)
	}
	//command.StatusChan.Close()
	//sender.Close()
	//remoteSender.Close()
	//client.Close()
	return response.Status
	//	os.Exit(response.Status)
}
Ejemplo n.º 22
0
// Misbehaving backends must be removed
func TestStackAddBad(t *testing.T) {
	s := NewStackSender()
	buf := Buffer{}
	s.Add(&buf)
	r, w := libchan.Pipe()
	s.Add(w)
	if s.Len() != 2 {
		t.Fatalf("%#v", s)
	}
	r.Close()
	if _, err := s.Send(&libchan.Message{Data: []byte("Log")}); err != nil {
		t.Fatal(err)
	}
	if s.Len() != 1 {
		t.Fatalf("%#v", s)
	}
	if len(buf) != 1 {
		t.Fatalf("%#v", buf)
	}
}
Ejemplo n.º 23
0
func TestStackWithPipe(t *testing.T) {
	r, w := libchan.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 string(msg.Data) != "Log" {
				t.Fatalf("%#v", msg)
			}
		}()
		_, err := s.Send(&libchan.Message{Data: []byte("Log")})
		if err != nil {
			t.Fatal(err)
		}
	})
}
Ejemplo n.º 24
0
func ComplexStructFuncs(b *testing.B) (BenchMessageSender, BenchMessageReceiver) {
	sender := func(i int, s libchan.Sender) {
		r, _ := io.Pipe()
		_, send := libchan.Pipe()
		v := &ComplexStruct{
			Value:  i,
			Sender: send,
			Reader: r,
		}
		if err := s.Send(v); err != nil {
			b.Fatalf("Error sending message: %s", err)
		}
	}
	receiver := func(i int, r libchan.Receiver) {
		var v ComplexStruct
		if err := r.Receive(&v); err != nil {
			b.Fatalf("Error receiving: %s", err)
		}
		if v.Value != i {
			b.Fatalf("Unexpected value received: %d != %d", v.Value, i)
		}
	}
	return sender, receiver
}
Ejemplo n.º 25
0
// Delete recursively deletes all objects stored at "path" and its subpaths.
func (driver *StorageDriverClient) Delete(path string) error {
	if err := driver.exited(); err != nil {
		return err
	}

	receiver, remoteSender := libchan.Pipe()
	params := map[string]interface{}{"Path": path}
	err := driver.sender.Send(&Request{Type: "Delete", Parameters: params, ResponseChannel: remoteSender})
	if err != nil {
		return err
	}

	response := new(DeleteResponse)
	err = driver.receiveResponse(receiver, response)
	if err != nil {
		return err
	}

	if response.Error != nil {
		return response.Error.Unwrap()
	}

	return nil
}
Ejemplo n.º 26
0
// CurrentSize retrieves the curernt size in bytes of the object at the given
// path.
func (driver *StorageDriverClient) CurrentSize(path string) (uint64, error) {
	if err := driver.exited(); err != nil {
		return 0, err
	}

	receiver, remoteSender := libchan.Pipe()
	params := map[string]interface{}{"Path": path}
	err := driver.sender.Send(&Request{Type: "CurrentSize", Parameters: params, ResponseChannel: remoteSender})
	if err != nil {
		return 0, err
	}

	response := new(CurrentSizeResponse)
	err = driver.receiveResponse(receiver, response)
	if err != nil {
		return 0, err
	}

	if response.Error != nil {
		return 0, response.Error.Unwrap()
	}

	return response.Position, nil
}
Ejemplo n.º 27
0
// WriteStream stores the contents of the provided io.ReadCloser at a location
// designated by the given path.
func (driver *StorageDriverClient) WriteStream(path string, offset, size int64, reader io.ReadCloser) error {
	if err := driver.exited(); err != nil {
		return err
	}

	receiver, remoteSender := libchan.Pipe()
	params := map[string]interface{}{"Path": path, "Offset": offset, "Size": size, "Reader": reader}
	err := driver.sender.Send(&Request{Type: "WriteStream", Parameters: params, ResponseChannel: remoteSender})
	if err != nil {
		return err
	}

	response := new(WriteStreamResponse)
	err = driver.receiveResponse(receiver, response)
	if err != nil {
		return err
	}

	if response.Error != nil {
		return response.Error.Unwrap()
	}

	return nil
}
Ejemplo n.º 28
0
func Pipe() (Receiver, Sender) {
	r, s := libchan.Pipe()
	return WrapReceiver(r), WrapSender(s)
}
Ejemplo n.º 29
0
// Start starts the designated child process storage driver and binds a socket
// to this process for IPC method calls
func (driver *StorageDriverClient) Start() error {
	driver.exitErr = nil
	driver.exitChan = make(chan error)
	driver.stopChan = make(chan struct{})

	fileDescriptors, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM, 0)
	if err != nil {
		return err
	}

	childSocket := os.NewFile(uintptr(fileDescriptors[0]), "childSocket")
	driver.socket = os.NewFile(uintptr(fileDescriptors[1]), "parentSocket")

	driver.subprocess.Stdout = os.Stdout
	driver.subprocess.Stderr = os.Stderr
	driver.subprocess.ExtraFiles = []*os.File{childSocket}

	if err = driver.subprocess.Start(); err != nil {
		driver.Stop()
		return err
	}

	go driver.handleSubprocessExit()

	if err = childSocket.Close(); err != nil {
		driver.Stop()
		return err
	}

	connection, err := net.FileConn(driver.socket)
	if err != nil {
		driver.Stop()
		return err
	}
	driver.transport, err = spdy.NewClientTransport(connection)
	if err != nil {
		driver.Stop()
		return err
	}
	driver.sender, err = driver.transport.NewSendChannel()
	if err != nil {
		driver.Stop()
		return err
	}

	// Check the driver's version to determine compatibility
	receiver, remoteSender := libchan.Pipe()
	err = driver.sender.Send(&Request{Type: "Version", ResponseChannel: remoteSender})
	if err != nil {
		driver.Stop()
		return err
	}

	var response VersionResponse
	err = receiver.Receive(&response)
	if err != nil {
		driver.Stop()
		return err
	}

	if response.Error != nil {
		return response.Error.Unwrap()
	}

	driver.version = response.Version

	if driver.version.Major() != storagedriver.CurrentVersion.Major() || driver.version.Minor() > storagedriver.CurrentVersion.Minor() {
		return IncompatibleVersionError{driver.version}
	}

	return nil
}
Ejemplo n.º 30
0
	AfterEach(func() {
		if clientConn != nil {
			clientConn.Close()
		}
		if serverListener != nil {
			fmt.Printf("Closing serverListener\n")
			serverListener.Close()
		}
		time.Sleep(10 * time.Millisecond)

		db.Close()
		os.RemoveAll(dbDir)
	})

	It("responds to echo requests", func() {
		responseRecv, responseSend := libchan.Pipe()

		req := &EchoRequest{
			Cmd:   "echo",
			Text:  "Hello world!",
			Reply: responseSend,
		}

		err := clientSender.Send(req)
		Ω(err).ShouldNot(HaveOccurred())

		response := &EchoReply{}
		err = responseRecv.Receive(response)
		Ω(err).ShouldNot(HaveOccurred())

		//fmt.Println(response.Text)