Example #1
0
func (c *Client) recv() {
	var headBuf = make([]byte, proto.HeadSize)
	var head proto.PkgHead

	var pkg []byte
	var err error
	for err == nil {
		pkg, err = proto.ReadPkg(c.r, headBuf, &head, nil)
		if err != nil {
			break
		}

		var call *Call
		var ok bool

		c.mtx.Lock()
		if call, ok = c.pending[head.Seq]; ok {
			delete(c.pending, head.Seq)
		}
		c.mtx.Unlock()

		if proto.CmdAuth == head.Cmd {
			c.cachAuth(pkg)
		}

		if call != nil {
			call.pkg = pkg
			call.ready = true
			call.done()
		}
	}

	// Terminate pending calls.
	c.mtx.Lock()
	c.shutdown = true
	if err == io.EOF {
		if c.closing {
			err = ErrShutdown
		} else {
			err = io.ErrUnexpectedEOF
		}
	}
	for _, call := range c.pending {
		call.err = err
		call.ready = true
		call.done()
	}
	c.mtx.Unlock()

	c.doClose()
}
Example #2
0
func (bin *BinLog) fixSeqFile(idx uint64) (fileInfo, error) {
	var fi fileInfo
	var name = bin.GetBinFileName(idx)
	file, err := os.Open(name)
	if err != nil {
		return fi, err
	}

	var r = bufio.NewReader(file)
	var headBuf = make([]byte, proto.HeadSize)
	var head proto.PkgHead
	for {
		_, err := proto.ReadPkg(r, headBuf, &head, nil)
		if err != nil {
			break
		}
		if fi.MinSeq == 0 {
			fi.MinSeq = head.Seq
			fi.Idx = idx
			fi.Done = true
		}
		if fi.MaxSeq < head.Seq {
			fi.MaxSeq = head.Seq
		}
	}

	file.Close()

	if fi.Idx == 0 {
		os.Remove(bin.GetBinFileName(idx))
		os.Remove(bin.GetSeqFileName(idx))
		return fi, fmt.Errorf("no record in bin file id %d", idx)
	}

	return fi, bin.writeSeqFile(&fi)
}
Example #3
0
func (c *Client) GoRecvRequest(ch *RequestChan, slv *slave) {
	var headBuf = make([]byte, proto.HeadSize)
	var head proto.PkgHead
	for {
		pkg, err := proto.ReadPkg(c.r, headBuf, &head, nil)
		if err != nil {
			if !c.IsClosed() && err != io.EOF && err != io.ErrUnexpectedEOF {
				log.Printf("ReadPkg failed: %s, close client!\n", err)
			}
			c.Close()
			return
		}

		//log.Printf("recv(%s): [0x%X\t%d\t%d]\n",
		//	c.c.RemoteAddr(), head.Cmd, head.DbId, head.Seq)

		var req = Request{c, slv, store.PkgArgs{head.Cmd, head.DbId, head.Seq, pkg}}

		switch head.Cmd {
		case proto.CmdAuth:
			fallthrough
		case proto.CmdPing:
			fallthrough
		case proto.CmdScan:
			fallthrough
		case proto.CmdMGet:
			fallthrough
		case proto.CmdGet:
			ch.ReadReqChan <- &req
		case proto.CmdMIncr:
			fallthrough
		case proto.CmdMDel:
			fallthrough
		case proto.CmdMSet:
			fallthrough
		case proto.CmdIncr:
			fallthrough
		case proto.CmdDel:
			fallthrough
		case proto.CmdSet:
			if ClientTypeNormal == c.ClientType() {
				ch.WriteReqChan <- &req
			} else {
				ch.SyncReqChan <- &req
			}
		case proto.CmdSyncSt:
			fallthrough
		case proto.CmdSync:
			if ClientTypeNormal != c.ClientType() {
				ch.SyncReqChan <- &req
			}
		case proto.CmdDump:
			ch.DumpReqChan <- &req
		case proto.CmdDelSlot:
			fallthrough
		case proto.CmdSlaveSt:
			fallthrough
		case proto.CmdMigrate:
			fallthrough
		case proto.CmdSlaveOf:
			ch.CtrlReqChan <- &req
		default:
			log.Printf("Invalid cmd 0x%X\n", head.Cmd)
			c.Close()
			return
		}
	}
}
Example #4
0
func (r *Reader) Init(lastSeq uint64) error {
	var err error
	r.bin.mtx.Lock()

	r.bin.rseqs = append(r.bin.rseqs, r.rseq)
	r.rseq.seq = lastSeq

	var index = -1
	for i, f := range r.bin.infos {
		index = i
		if lastSeq < f.MinSeq {
			break
		}

		if f.MaxSeq >= lastSeq || f.MaxSeq == 0 {
			break
		}
	}

	if index < 0 {
		r.bin.mtx.Unlock() // unlock immediately
		if lastSeq > 0 && lastSeq != MinNormalSeq {
			return ErrLogMissing
		}
		r.curMemPos = -1
		r.curInfo.Idx = 0
		return nil
	} else {
		r.curInfo = *r.bin.infos[index]
		if lastSeq > 0 && lastSeq != MinNormalSeq && r.curInfo.MinSeq > lastSeq+1 {
			r.bin.mtx.Unlock() // unlock immediately
			return ErrLogMissing
		}
	}

	r.rseq.seq = r.curInfo.MinSeq

	if r.curInfo.Done {
		r.bin.mtx.Unlock() // unlock immediately

		var name = r.bin.GetBinFileName(r.curInfo.Idx)
		r.curFile, err = os.Open(name)
		if err != nil {
			log.Printf("open file failed: (%s) %s\n", name, err)
			return err
		}

		if r.curBufR == nil {
			r.curBufR = bufio.NewReader(r.curFile)
		} else {
			r.curBufR.Reset(r.curFile)
		}

		if r.curInfo.MinSeq < lastSeq+1 {
			var pkgBuf = make([]byte, 4096)
			for {
				_, err = proto.ReadPkg(r.curBufR, r.headBuf, &r.head, pkgBuf)
				if err != nil {
					return err
				}

				if r.head.Seq >= lastSeq {
					break
				}
			}
		}
	} else {
		defer r.bin.mtx.Unlock() // wait until func finished

		if r.curInfo.Idx != r.bin.fileIdx {
			log.Printf("invalid file index (%d, %d)\n", r.curInfo.Idx, r.bin.fileIdx)
			return ErrUnexpected
		}
		r.curMemPos = 0

		if r.curInfo.MinSeq < lastSeq+1 {
			for {
				if r.curMemPos+proto.HeadSize > r.bin.usedLen {
					return ErrUnexpected
				}

				_, err = r.head.Decode(r.bin.memlog[r.curMemPos:])
				if err != nil {
					return ErrUnexpected
				}

				if r.curMemPos+int(r.head.PkgLen) > r.bin.usedLen {
					return ErrUnexpected
				}

				r.curMemPos += int(r.head.PkgLen)
				if r.head.Seq >= lastSeq {
					break
				}
			}
		}
	}

	return nil
}
Example #5
0
func (r *Reader) next() []byte {
	var err error
	if r.curFile != nil {
		pkg, err := proto.ReadPkg(r.curBufR, r.headBuf, &r.head, nil)
		if err != nil {
			return r.nextFile()
		}

		return pkg
	} else if r.curMemPos >= 0 {
		r.bin.mtx.Lock()
		if r.curInfo.Idx != r.bin.fileIdx {
			for _, f := range r.bin.infos {
				if f.Idx == r.curInfo.Idx {
					r.curInfo = *f
					break
				}
			}
			r.bin.mtx.Unlock() // unlock immediately

			var name = r.bin.GetBinFileName(r.curInfo.Idx)
			r.curFile, err = os.Open(name)
			if err != nil {
				log.Printf("open file failed: (%s) %s\n", name, err)
				return nil
			}

			if r.curBufR == nil {
				r.curBufR = bufio.NewReader(r.curFile)
			} else {
				r.curBufR.Reset(r.curFile)
			}

			r.curFile.Seek(int64(r.curMemPos), 0)
			r.curMemPos = -1
			return r.next()
		}

		defer r.bin.mtx.Unlock() // wait to finish

		if r.curMemPos+proto.HeadSize > r.bin.usedLen {
			return nil
		}
		_, err = r.head.Decode(r.bin.memlog[r.curMemPos:])
		if err != nil {
			return nil
		}

		if r.curMemPos+int(r.head.PkgLen) > r.bin.usedLen {
			return nil
		}

		var pkg = make([]byte, int(r.head.PkgLen))
		copy(pkg, r.bin.memlog[r.curMemPos:])

		r.curMemPos += int(r.head.PkgLen)
		return pkg
	} else {
		return r.nextFile()
	}

	return nil
}