func (rs *RemoteServer) serveStream(stream net.Conn) { defer stream.Close() start := time.Now() conn, err := net.Dial("tcp", rs.raddr) if err != nil { log.Error("connect to remote error:%v", err) return } defer conn.Close() atomic.AddInt32(&rs.streamCount, 1) streamID := atomic.AddUint64(&rs.streamID, 1) readChan := make(chan int64, 1) writeChan := make(chan int64, 1) var readBytes int64 var writeBytes int64 go pipe(stream, conn, readChan) go pipe(conn, stream, writeChan) for i := 0; i < 2; i++ { select { case readBytes = <-readChan: stream.Close() log.Debug("[#%d] read %d bytes", streamID, readBytes) case writeBytes = <-writeChan: // DON'T call conn.Close, it will trigger an error in pipe. // Just close stream, let the conn copy finished normally log.Debug("[#%d] write %d bytes", streamID, writeBytes) } } log.Info("[#%d] r:%d w:%d t:%v c:%d", streamID, readBytes, writeBytes, time.Now().Sub(start), atomic.LoadInt32(&rs.streamCount)) atomic.AddInt32(&rs.streamCount, -1) }
func (ls *LocalServer) transport(conn net.Conn) { defer conn.Close() start := time.Now() stream, err := ls.openStream() if err != nil { log.Error("open stream for %s error:%v", conn.RemoteAddr().String(), err) return } defer stream.Close() atomic.AddInt32(&ls.streamCount, 1) streamID := atomic.AddUint64(&ls.streamID, 1) readChan := make(chan int64, 1) writeChan := make(chan int64, 1) var readBytes int64 var writeBytes int64 go pipe(conn, stream, readChan) go pipe(stream, conn, writeChan) for i := 0; i < 2; i++ { select { case readBytes = <-readChan: // DON'T call conn.Close, it will trigger an error in pipe. // Just close stream, let the conn copy finished normally log.Debug("[#%d] read %d bytes", streamID, readBytes) case writeBytes = <-writeChan: stream.Close() log.Debug("[#%d] write %d bytes", streamID, writeBytes) } } log.Info("[#%d] r:%d w:%d t:%v c:%d", streamID, readBytes, writeBytes, time.Now().Sub(start), atomic.LoadInt32(&ls.streamCount)) atomic.AddInt32(&ls.streamCount, -1) }
// RegisterTmp create a ephemeral node, and watch it, if node droped then send a SIGQUIT to self. func RegisterTemp(conn *zk.Conn, fpath string, data []byte) error { tpath, err := conn.Create(path.Join(fpath)+"/", data, zk.FlagEphemeral|zk.FlagSequence, zk.WorldACL(zk.PermAll)) if err != nil { log.Error("conn.Create(\"%s\", \"%s\", zk.FlagEphemeral|zk.FlagSequence) error(%v)", fpath, string(data), err) return err } log.Debug("create a zookeeper node:%s", tpath) // watch self go func() { for { log.Info("zk path: \"%s\" set a watch", tpath) exist, _, watch, err := conn.ExistsW(tpath) if err != nil { log.Error("zk.ExistsW(\"%s\") error(%v)", tpath, err) log.Warn("zk path: \"%s\" set watch failed, kill itself", tpath) killSelf() return } if !exist { log.Warn("zk path: \"%s\" not exist, kill itself", tpath) killSelf() return } event := <-watch log.Info("zk path: \"%s\" receive a event %v", tpath, event) } }() return nil }
func readWritable(c net.Conn) (readable, writable bool) { readable = true writable = true c.SetReadDeadline(time.Now().Add(10 * time.Millisecond)) buf := make([]byte, 1) _, err := c.Read(buf) if err != nil && err == io.EOF { readable = false log.Debug("detect readable error:%v", err) } c.SetReadDeadline(time.Time{}) c.SetWriteDeadline(time.Now().Add(10 * time.Millisecond)) if _, err := c.Write(buf); err != nil { writable = false log.Debug("detect writable error:%v", err) } c.SetWriteDeadline(time.Time{}) return }
// Connect connect to zookeeper, and start a goroutine log the event. func Connect(addr []string, timeout time.Duration) (*zk.Conn, error) { conn, session, err := zk.Connect(addr, timeout) if err != nil { log.Error("zk.Connect(\"%v\", %d) error(%v)", addr, timeout, err) return nil, err } go func() { for { event := <-session log.Debug("zookeeper get a event: %s", event.State.String()) } }() return conn, nil }
// Create create zookeeper path, if path exists ignore error func Create(conn *zk.Conn, fpath string) error { // create zk root path tpath := "" for _, str := range strings.Split(fpath, "/")[1:] { tpath = path.Join(tpath, "/", str) log.Debug("create zookeeper path: \"%s\"", tpath) _, err := conn.Create(tpath, []byte(""), 0, zk.WorldACL(zk.PermAll)) if err != nil { if err == zk.ErrNodeExists { log.Warn("zk.create(\"%s\") exists", tpath) } else { log.Error("zk.create(\"%s\") error(%v)", tpath, err) return err } } } return nil }