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 }
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 }
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") } } }
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)) }
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 }
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) } }
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 }
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 }
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 }
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 }
// 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 }
// 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 }
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 }
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) } }
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) }
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) }
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") } } }
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) } }
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) }
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) }
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) }
// 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) } }
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) } }) }
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 }
// 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 }
// 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 }
// 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 }
func Pipe() (Receiver, Sender) { r, s := libchan.Pipe() return WrapReceiver(r), WrapSender(s) }
// 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 }
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)