func (self *LevelDbDatastore) LogRequestAndAssignSequenceNumber(request *protocol.Request, replicationFactor *uint8, ownerServerId *uint32) error { // log to this key structure on a different DB sharded by day: <cluster version><owner id><sequence server id><replication sequence> var numberKey []byte if request.SequenceNumber == nil { sequenceNumber, err := self.AtomicIncrement(self.keyForOwnerAndServerSequenceNumber(request.ClusterVersion, replicationFactor, ownerServerId, request.OriginatingServerId), 1) if err != nil { return err } request.SequenceNumber = &sequenceNumber } else { // this is for a replicated write, ensure that it's the next in line for this owner and server name := self.keyForOwnerAndServerSequenceNumber(request.ClusterVersion, replicationFactor, ownerServerId, request.OriginatingServerId) numberKey = append(ATOMIC_INCREMENT_PREFIX, []byte(name)...) numberBytes, err := self.db.Get(self.readOptions, numberKey) if err != nil { return err } previousSequenceNumber := self.bytesToCurrentNumber(numberBytes) if previousSequenceNumber+uint64(1) != *request.SequenceNumber { return SequenceMissingRequestsError{"Missing requests between last seen and this one.", previousSequenceNumber} } } self.requestLogLock.RLock() requestLog := self.currentRequestLog self.requestLogLock.RUnlock() // proxied writes should be logged as replicated ones. That's what is expected if they're replayed later if *request.Type == protocol.Request_PROXY_WRITE { request.Type = &replicateWrite } data, err := request.Encode() if err != nil { return err } key := self.requestLogKey(request.ClusterVersion, request.OriginatingServerId, ownerServerId, request.SequenceNumber, replicationFactor) err = requestLog.db.Put(self.writeOptions, key, data) if err != nil { return err } if numberKey != nil { currentNumberBuffer := bytes.NewBuffer(make([]byte, 0, 8)) binary.Write(currentNumberBuffer, binary.BigEndian, *request.SequenceNumber) self.db.Put(self.writeOptions, numberKey, currentNumberBuffer.Bytes()) } return nil }
func (self *LevelDbDatastore) LogRequestAndAssignSequenceNumber(request *protocol.Request, replicationFactor *uint8, ownerServerId *uint32) error { // log to this key structure on a different DB sharded by day: <cluster version><owner id><sequence server id><replication sequence> updateSequenceNumber := false if request.SequenceNumber == nil { sequenceNumber, err := self.AtomicIncrement(self.keyForOwnerAndServerSequenceNumber(request.ClusterVersion, replicationFactor, ownerServerId, request.OriginatingServerId), 1) if err != nil { return err } request.SequenceNumber = &sequenceNumber } else { updateSequenceNumber = true previousSequenceNumber, err := self.CurrentSequenceNumber(request.ClusterVersion, replicationFactor, ownerServerId, request.OriginatingServerId) if err != nil { return err } // Do a less than comparison because it's ok if we're just getting the same write again. As long as we haven't missed one. if previousSequenceNumber+uint64(1) < *request.SequenceNumber { log.Warn("MISSING REQUESTS: %d, %d", previousSequenceNumber, *request.SequenceNumber) return SequenceMissingRequestsError{"Missing requests between last seen and this one.", previousSequenceNumber, *request.SequenceNumber} } } self.requestLogLock.RLock() requestLog := self.currentRequestLog self.requestLogLock.RUnlock() // proxied writes should be logged as replicated ones. That's what is expected if they're replayed later if *request.Type == protocol.Request_PROXY_WRITE { request.Type = &replicateWrite } data, err := request.Encode() if err != nil { return err } key := NewWALKey(request.ClusterVersion, request.OriginatingServerId, ownerServerId, request.SequenceNumber, replicationFactor) err = requestLog.db.Put(self.writeOptions, key, data) if err != nil { return err } if updateSequenceNumber { return self.updateSequenceNumber(request.ClusterVersion, replicationFactor, ownerServerId, request.OriginatingServerId, *request.SequenceNumber) } return nil }
func (self *DatastoreMock) LogRequestAndAssignSequenceNumber(request *protocol.Request, replicationFactor *uint8, ownerServerId *uint32) error { id := uint64(1) request.SequenceNumber = &id return nil }