// readSkews reads all clock data for the client's namespace. func (client *client) readSkews(collection mongo.Collection) (map[string]Skew, error) { // Read the clock document, recording the time before and after completion. readBefore := client.config.Clock.Now() var clockDoc clockDoc if err := collection.FindId(client.clockDocId()).One(&clockDoc); err != nil { return nil, errors.Trace(err) } readAfter := client.config.Clock.Now() if err := clockDoc.validate(); err != nil { return nil, errors.Annotatef(err, "corrupt clock document") } // Create skew entries for each known writer... skews, err := clockDoc.skews(readBefore, readAfter) if err != nil { return nil, errors.Trace(err) } // If a writer was previously known to us, and has not written since last // time we read, we should keep the original skew, which is more accurate. for writer, skew := range client.skews { if skews[writer].LastWrite == skew.LastWrite { skews[writer] = skew } } // ...and overwrite our own with a zero skew, which will DTRT (assuming // nobody's reusing client ids across machines with different clocks, // which *should* never happen). skews[client.config.Id] = Skew{} return skews, nil }
// exists returns whether the identified refcount doc exists. func (nsRefcounts_) exists(coll mongo.Collection, key string) (bool, error) { count, err := coll.FindId(key).Count() if err != nil { return false, errors.Trace(err) } return count != 0, nil }
// read returns the value stored in the identified refcount doc. func (nsRefcounts_) read(coll mongo.Collection, key string) (int, error) { var doc refcountDoc if err := coll.FindId(key).One(&doc); err == mgo.ErrNotFound { return 0, errors.NotFoundf("refcount %q", key) } else if err != nil { return 0, errors.Trace(err) } return doc.RefCount, nil }
// setStatusOp returns a txn.Op that updates the status of the // identified payload. If the payload doesn't exist, it returns // errAlreadyRemoved. func (nsPayloads_) setStatusOp(payloads mongo.Collection, docID string, status string) (txn.Op, error) { count, err := payloads.FindId(docID).Count() if err != nil { return txn.Op{}, errors.Trace(err) } else if count == 0 { return txn.Op{}, errAlreadyRemoved } return txn.Op{ C: payloads.Name(), Id: docID, Assert: txn.DocExists, Update: bson.D{{"$set", bson.D{{"state", status}}}}, }, nil }
// untrackOp returns a txn.Op that will unconditionally remove the // identified document. If the payload doesn't exist, it returns // errAlreadyRemoved. func (nsPayloads_) untrackOp(payloads mongo.Collection, docID string) (txn.Op, error) { count, err := payloads.FindId(docID).Count() if err != nil { return txn.Op{}, errors.Trace(err) } else if count == 0 { return txn.Op{}, errAlreadyRemoved } return txn.Op{ C: payloads.Name(), Id: docID, Assert: txn.DocExists, Remove: true, }, nil }
// trackOp returns a txn.Op that will either insert or update the // supplied payload, and fail if the observed precondition changes. func (nsPayloads_) trackOp(payloads mongo.Collection, doc payloadDoc) (txn.Op, error) { docID := nsPayloads.docID(doc.UnitID, doc.Name) payloadOp := txn.Op{ C: payloads.Name(), Id: docID, } count, err := payloads.FindId(docID).Count() if err != nil { return txn.Op{}, errors.Trace(err) } else if count == 0 { payloadOp.Assert = txn.DocMissing payloadOp.Insert = doc } else { payloadOp.Assert = txn.DocExists payloadOp.Update = bson.D{{"$set", doc}} } return payloadOp, nil }