Ejemplo n.º 1
0
// Commit takes a storage transaction and writes any headers or indexes to make
// the transacted facts visible. A storage transaction is passed in to enable
// the writes to occur atomically which ensures consistency of the transacted
// facts.
func (p *Pipeline) Commit(tx storage.Tx) error {
	var (
		err error
		log *dal.Log
	)

	// Write the remaining block of the segment.
	if err = p.segment.Commit(tx); err != nil {
		return err
	}

	// No new facts, remove the segment.
	if p.segment.Count == 0 {
		logrus.Debugf("pipeline: no facts written to %s, removing segment", p.Domain)
		p.segment.Abort(tx)
		return nil
	}

	logrus.Debugf("pipeline: %d facts written to %s", p.segment.Count, p.Domain)

	// Compare and swap ID on domain's commit log.
	if log, err = dal.GetLog(tx, p.Domain, commitLogName); err != nil {
		return err
	}

	// Existing commit log, check if the head is the same.
	if log != nil {
		// TODO: determine path to handle conflicts.
		if log.Head != nil && !uuid.Equal(*log.Head, *p.segment.Base) {
			return ErrCommitConflict
		}
	} else {
		log = &dal.Log{
			Name:   commitLogName,
			Domain: p.Domain,
		}
	}

	log.Head = p.segment.UUID

	_, err = dal.SetLog(tx, p.Domain, log)

	return err
}
Ejemplo n.º 2
0
// Init initializes the pipeline for the transaction.
func (p *Pipeline) Init(tx *Transaction) error {
	// Get the commit log for this domain.
	log, err := dal.GetLog(tx.Engine, p.Domain, commitLogName)

	if err != nil {
		return err
	}

	if log == nil {
		log = &dal.Log{}
	}

	// Initialize new segment pointing to the head of the log.
	p.segment = NewSegment(tx.Engine, p.Domain, tx.ID)
	p.segment.Base = log.Head
	p.segment.Next = log.Head
	p.segment.Time = tx.StartTime
	p.engine = tx.Engine
	p.dedupe = !tx.options.AllowDuplicates

	return nil
}