func (pr *PipeRouter) getOrCreate(id string) (*pipe, bool) { pr.Lock() defer pr.Unlock() p, ok := pr.pipes[id] if !ok { log.Printf("Creating pipe id %s", id) p = &pipe{ ui: end{lastUsedTime: mtime.Now()}, probe: end{lastUsedTime: mtime.Now()}, Pipe: xfer.NewPipe(), } pr.pipes[id] = p } if p.Closed() { return nil, false } return p, true }
func (pr *localPipeRouter) Get(_ context.Context, id string, e End) (xfer.Pipe, io.ReadWriter, error) { pr.Lock() defer pr.Unlock() p, ok := pr.pipes[id] if !ok { log.Infof("Creating pipe id %s", id) p = &pipe{ ui: end{lastUsedTime: mtime.Now()}, probe: end{lastUsedTime: mtime.Now()}, Pipe: xfer.NewPipe(), } pr.pipes[id] = p } if p.Closed() { return nil, nil, fmt.Errorf("Pipe %s closed", id) } end, endIO := p.end(e) end.refCount++ return p, endIO, nil }
PipeClose(string, string) error } // pipe is the probe-local type for a pipe, extending // xfer.Pipe with the appID and a custom closer method. type pipe struct { xfer.Pipe id, appID string client PipeClient } // NewPipe creats a new pipe and connects it to the app. var NewPipe = func(c PipeClient, appID string) (string, xfer.Pipe, error) { pipeID := fmt.Sprintf("pipe-%d", rand.Int63()) pipe := &pipe{ Pipe: xfer.NewPipe(), appID: appID, id: pipeID, client: c, } if err := c.PipeConnection(appID, pipeID, pipe.Pipe); err != nil { return "", nil, err } return pipeID, pipe, nil } func (p *pipe) Close() error { err1 := p.Pipe.Close() err2 := p.client.PipeClose(p.appID, p.id) if err1 != nil { return err1