// Talk with local agent func NewChannel(name string, port int, wg *sync.WaitGroup) (chan []byte, error) { ch := make(chan []byte) // connect to a TCP server network := "tcp" target := "localhost:" + strconv.Itoa(port) raddr, err := net.ResolveTCPAddr(network, target) if err != nil { return ch, fmt.Errorf("Fail to resolve %s: %v", target, err) } conn, err := net.DialTCP(network, nil, raddr) if err != nil { return ch, fmt.Errorf("Fail to dial %s: %v", raddr, err) } wg.Add(1) go func() { defer wg.Done() defer conn.Close() buf := make([]byte, 4) util.WriteBytes(conn, buf, util.NewMessage(util.Data, []byte("PUT "+name))) for data := range ch { util.WriteBytes(conn, buf, util.NewMessage(util.Data, data)) } util.WriteBytes(conn, buf, util.NewMessage(util.CloseChannel, nil)) }() return ch, nil }
func (rc *ReceiveChannel) receiveTopicFrom(target string) { // connect to a TCP server network := "tcp" raddr, err := net.ResolveTCPAddr(network, target) if err != nil { log.Printf("Fail to resolve %s:%v", target, err) return } // println("dial tcp", raddr.String()) conn, err := net.DialTCP(network, nil, raddr) if err != nil { log.Printf("Fail to dial %s:%v", raddr, err) time.Sleep(time.Second) return } defer conn.Close() buf := make([]byte, 4) util.WriteBytes(conn, buf, util.NewMessage(util.Data, []byte("GET "+rc.name))) util.WriteUint64(conn, rc.offset) util.WriteBytes(conn, buf, util.NewMessage(util.Data, []byte("ok"))) ticker := time.NewTicker(time.Millisecond * 1100) defer ticker.Stop() go func() { buf := make([]byte, 4) for range ticker.C { util.WriteBytes(conn, buf, util.NewMessage(util.Data, []byte("ok"))) // print(".") } }() for { f, data, err := util.ReadBytes(conn, buf) if err == io.EOF { // print("recieve close chan2: eof") break } if err != nil { log.Printf("receive error:%v", err) continue } rc.offset += 4 + 1 if f != util.Data { // print("recieve close chan1: ", string([]byte{byte(f)})) break } // println("receive raw data :", string(data.Bytes())) rc.offset += uint64(len(data.Data())) rc.Ch <- data.Data() } close(rc.Ch) }
func (as *AgentServer) handleWriteConnection(r io.Reader, name string) { as.name2StoreLock.Lock() ds, ok := as.name2Store[name] if !ok { s, err := store.NewLocalFileDataStore(as.dir, fmt.Sprintf("%s-%d", name, as.Port)) if err != nil { log.Printf("Failed to create a queue on disk: %v", err) as.name2StoreLock.Unlock() return } as.name2Store[name] = NewLiveDataStore(s) ds = as.name2Store[name] //register stream go client.NewHeartBeater(name, as.Port, "localhost:8930").StartHeartBeat(ds.killHeartBeater) } as.name2StoreLock.Unlock() buf := make([]byte, 4) for { _, message, err := util.ReadBytes(r, buf) if err == io.EOF { // println("agent recv eof:", string(message.Bytes())) break } if err == nil { util.WriteBytes(ds.store, buf, message) // println("agent recv:", string(message.Bytes())) } if message.Flag() != util.Data { // println("finished writing", name) break } } }
func (as *AgentServer) handleLocalReadConnection(conn net.Conn, name string, offset int64) { as.name2StoreLock.Lock() ds, ok := as.name2Store[name] if !ok { s, err := store.NewLocalFileDataStore(as.dir, fmt.Sprintf("%s-%d", name, as.Port)) if err != nil { // log.Printf("Failed to create queue on disk: %v", err) as.name2StoreLock.Unlock() return } as.name2Store[name] = NewLiveDataStore(s) ds = as.name2Store[name] } as.name2StoreLock.Unlock() closeSignal := make(chan bool, 1) go func() { buf := make([]byte, 4) for false { // println("wait for reader heartbeat") conn.SetReadDeadline(time.Now().Add(2500 * time.Millisecond)) _, _, err := util.ReadBytes(conn, buf) if err != nil { fmt.Printf("connection is closed? (%v)\n", err) closeSignal <- true close(closeSignal) return } } }() buf := make([]byte, 4) // loop for every read for { _, err := ds.store.ReadAt(buf, offset) if err != nil { // connection is closed if err != io.EOF { log.Printf("Read size from %s offset %d: %v", name, offset, err) } // println("got problem reading", name, offset, err.Error()) return } offset += 4 size := util.BytesToUint32(buf) // println("reading", name, offset, "size:", size) messageBytes := make([]byte, size) _, err = ds.store.ReadAt(messageBytes, offset) if err != nil { // connection is closed if err != io.EOF { log.Printf("Read data from %s offset %d: %v", name, offset, err) } return } offset += int64(size) m := util.LoadMessage(messageBytes) // println(name, "sent:", len(messageBytes), ":", string(m.Data())) util.WriteBytes(conn, buf, m) if m.Flag() != util.Data { // println("Finished reading", name) break } } }