예제 #1
0
func (rec *Receiver) fetch() error {
	fetch := store.FetchRequest{
		Partition:     rec.path.Partition(),
		MessageC:      make(chan store.MessageAndId, 3),
		ErrorCallback: make(chan error),
		StartCallback: make(chan int),
		Prefix:        []byte(rec.path),
		Count:         rec.maxCount,
	}

	if rec.startId >= 0 {
		fetch.Direction = 1
		fetch.StartId = uint64(rec.startId)
		if rec.maxCount == 0 {
			fetch.Count = math.MaxInt32
		}
	} else {
		fetch.Direction = 1
		maxId, err := rec.messageStore.MaxMessageId(rec.path.Partition())
		if err != nil {
			return err
		}
		fetch.StartId = maxId + 1 + uint64(rec.startId)
		if rec.maxCount == 0 {
			fetch.Count = -1 * int(rec.startId)
		}
	}

	rec.messageStore.Fetch(fetch)

	for {
		select {
		case numberOfResults := <-fetch.StartCallback:
			rec.sendOK(protocol.SUCCESS_FETCH_START, fmt.Sprintf("%v %v", rec.path, numberOfResults))
		case msgAndId, open := <-fetch.MessageC:
			if !open {
				rec.sendOK(protocol.SUCCESS_FETCH_END, string(rec.path))
				return nil
			}

			logger.WithFields(log.Fields{
				"msgId": msgAndId.Id,
				"msg":   string(msgAndId.Message),
			}).Debug("Reply sen to")

			rec.lastSendId = msgAndId.Id
			rec.sendC <- msgAndId.Message
		case err := <-fetch.ErrorCallback:
			return err
		case <-rec.cancelC:
			rec.shouldStop = true
			rec.sendOK(protocol.SUCCESS_CANCELED, string(rec.path))
			// TODO implement cancellation in message store
			return nil
		}
	}
}
예제 #2
0
파일: receiver.go 프로젝트: tkrille/guble
func (rec *Receiver) fetch() error {
	var err error

	fetch := store.FetchRequest{
		Partition:     rec.path.Partition(),
		MessageC:      make(chan store.MessageAndId, 3),
		ErrorCallback: make(chan error),
		StartCallback: make(chan int),
		Prefix:        []byte(rec.path),
		Count:         rec.maxCount,
	}

	if rec.startId >= 0 {
		fetch.Direction = 1
		fetch.StartId = uint64(rec.startId)
		if rec.maxCount == 0 {
			fetch.Count = math.MaxInt32
		}
	} else {
		fetch.Direction = -1
		if fetch.StartId, err = rec.messageStore.MaxMessageId(rec.path.Partition()); err != nil {
			return err
		}
		if rec.maxCount == 0 {
			fetch.Count = -1 * int(rec.startId)
		}
	}

	rec.messageStore.Fetch(fetch)

	for {
		select {
		case numberOfResults := <-fetch.StartCallback:
			rec.sendOK(guble.SUCCESS_FETCH_START, fmt.Sprintf("%v %v", rec.path, numberOfResults))
		case msgAndId, open := <-fetch.MessageC:
			if !open {
				rec.sendOK(guble.SUCCESS_FETCH_END, string(rec.path))
				return nil
			}
			guble.Debug("replay send %v, %v", msgAndId.Id, string(msgAndId.Message))
			rec.lastSendId = msgAndId.Id
			rec.sendChannel <- msgAndId.Message
		case err := <-fetch.ErrorCallback:
			return err
		case <-rec.cancelChannel:
			rec.shouldStop = true
			rec.sendOK(guble.SUCCESS_CANCELED, string(rec.path))
			// TODO implement cancellation in message store
			return nil
		}
	}
}