Beispiel #1
0
func (m *diskMailbox) Nack(id vega.MessageId) error {
	m.Lock()
	defer m.Unlock()

	idxStr := id.LocalIndex()
	if idxStr == "" {
		return vega.EUnknownMessage
	}

	idx, err := strconv.Atoi(idxStr)
	if err != nil {
		return err
	}

	db := m.disk.db

	return db.Update(func(tx *bolt.Tx) error {
		var header mailboxHeader

		buk := tx.Bucket(m.prefix)

		data := buk.Get(cMInfo)
		if data == nil {
			return vega.EUnknownMessage
		}

		diskDataUnmarshal(data, &header)

		if idx < header.AckIndex || idx >= header.ReadIndex {
			return vega.EUnknownMessage
		}

		header.InFlight--

		// optimization, nack'ing the last read message
		if idx == header.ReadIndex-1 {
			header.ReadIndex--
			header.Size++
		} else {
			header.DCMessages = append(header.DCMessages, idx)
		}

		headerData, err := diskDataMarshal(&header)
		if err != nil {
			return err
		}

		return buk.Put(cMInfo, headerData)
	})
}
Beispiel #2
0
func (m *diskMailbox) Ack(id vega.MessageId) error {
	m.Lock()
	defer m.Unlock()

	db := m.disk.db

	return db.Update(func(tx *bolt.Tx) error {

		buk := tx.Bucket(m.prefix)

		data := buk.Get(cMInfo)

		if len(data) == 0 {
			return vega.EUnknownMessage
		}

		var header mailboxHeader

		err := diskDataUnmarshal(data, &header)
		if err != nil {
			return ECorruptMailbox
		}

		idxStr := id.LocalIndex()
		if idxStr == "" {
			return vega.EUnknownMessage
		}

		idx, err := strconv.Atoi(idxStr)
		if err != nil {
			return err
		}

		// debugf("acking message %d (AckIndex: %d)\n", idx, header.AckIndex)

		if header.ReadIndex-header.AckIndex == 0 {
			return vega.EUnknownMessage
		}

		if idx < header.AckIndex || idx >= header.ReadIndex {
			return vega.EUnknownMessage
		}

		// Messages may be ack'd incontigiously. That's fine, we'll
		// just track AckIndex as the oldest un-acked message.
		if header.AckIndex == idx {
			header.AckIndex++
		}

		key := append(cMessagePrefix, []byte(idxStr)...)

		err = buk.Delete(key)
		if err != nil {
			return err
		}

		header.InFlight--

		headerData, err := diskDataMarshal(&header)
		if err != nil {
			return err
		}

		return buk.Put(cMInfo, headerData)
	})
}