private bool CheckAndRemoveIfExpired(KvKey key, VectorClock currentClock, KvMetadata metadataToCheck, WriteTransaction txn = null) { if (metadataToCheck == null || metadataToCheck.Status == Active && currentClock.TicksOffsetUtc < metadataToCheck.Expiry.TicksOffsetUtc) { return(true); } if (metadataToCheck.Status == Active && currentClock.TicksOffsetUtc < metadataToCheck.Expiry.TicksOffsetUtc) { if (txn != null) { RemoveExpired(txn, ToTableKey(key), metadataToCheck.Expiry); } else { _lmdb.WriteAsync(tx => RemoveExpired(tx, ToTableKey(key), metadataToCheck.Expiry), false); } } return(false); }
public TableKey ToTableKey(KvKey key) => new TableKey(key.Key);
public KvMetadata TryGetMetadata(AbstractTransaction txn, KvKey key) => _metadataTable.TryGet(txn, key);
public KvKey[] KeysByPrefix(AbstractTransaction txn, KvKey startFrom, uint page, uint pageSize) => txn.KeysByPrefix(_table, ToTableKey(startFrom), page, pageSize).Select(FromTableKey).ToArray();
public void Erase(WriteTransaction txn, KvKey key) => txn.Delete(_table, ToTableKey(key));
public bool AddOrUpdate(WriteTransaction txn, KvKey key, KvMetadata metadata) => txn.AddOrUpdate(_table, ToTableKey(key), ToTableValue(metadata));
public KvMetadata TryGet(AbstractTransaction txn, KvKey key) => TryGet(txn, ToTableKey(key));
public async Task <ulong> SyncHandler(WriteLogEvent syncEvent) { var posn = syncEvent.LocallySaved.GetReplicaValue(_targetReplicaId); if (!posn.HasValue) { throw new EventLogException($"Broken syncEvent.LocallySaved during replication '{syncEvent.LocallySaved}'. For replica '{_targetReplicaId}'"); } var pos = posn.Value; if (_cancellationToken.IsCancellationRequested) { return(pos); } switch (syncEvent.LoggedEventCase) { case WriteLogEvent.LoggedEventOneofCase.Updated: var addedOrUpdated = syncEvent.Updated; await _lmdb.WriteAsync(txn => { var addMetadata = new KvMetadata { Status = Active, Expiry = addedOrUpdated.Expiry, Action = Replicated, Originated = syncEvent.Originated, ValueMetadata = syncEvent.ValueMetadata, CorrelationId = syncEvent.CorrelationId }; var wasUpdated = _kvTable.Add( txn, new KvKey(addedOrUpdated.Key), addMetadata, new KvValue(addedOrUpdated.Value), (key, vcOld, vcNew) => vcOld.Earlier(vcNew)); _replicationTable.SetLastPos(txn, _targetReplicaId, pos); _kvTable.StatusTable.IncrementCounters(txn, replicatedAdds: 1); // TODO: Should we do anything if the value wasn't updated? Maybe logging? }, false, true); break; case WriteLogEvent.LoggedEventOneofCase.Deleted: var deleted = syncEvent.Deleted; await _lmdb.WriteAsync(txn => { _updateClock(txn, _targetReplicaId, syncEvent.LocallySaved.GetReplicaValue(_targetReplicaId)); var delMetadata = new KvMetadata { Status = KvMetadata.Types.Status.Deleted, Expiry = syncEvent.LocallySaved.TicksOffsetUtc.ToTimestamp(), Action = Replicated, Originated = syncEvent.Originated, OriginatorReplicaId = syncEvent.OriginatorReplicaId, CorrelationId = syncEvent.CorrelationId, ValueMetadata = syncEvent.ValueMetadata, }; var kvKey = new KvKey(deleted.Key); _kvTable.Delete(txn, kvKey, delMetadata); _replicationTable.SetLastPos(txn, _targetReplicaId, pos); _kvTable.StatusTable.IncrementCounters(txn, replicatedDeletes: 1); // TODO: Should we do anything if the value wasn't updated? Maybe logging? }, false, true); break; case WriteLogEvent.LoggedEventOneofCase.None: throw new ArgumentException("syncEvent", $"Unexpected LogEvent case: {syncEvent.LoggedEventCase}"); default: throw new ArgumentOutOfRangeException(); } return(pos); }