public async Task <AddResponse> Add(IEnumerable <AddRequestEntry> entries, Header header) { var batch = entries.Select(ks => (new KvKey(ks.Key), new KvMetadata { Status = Active, Expiry = ks.Expiry, Action = Added, CorrelationId = header.CorrelationId, ValueMetadata = ks.ValueMetadata }, new KvValue(ks.Value))).ToArray(); var ret = await(header.OverrideExisting ? _kvTable.AddOrUpdate(batch) : _kvTable.Add(batch)); var response = new AddResponse(); var addResults = ret.Select(kv => kv.Item2 ? (header.OverrideExisting ? AddResult.KeyUpdated : AddResult.KeyAdded) // TODO: Recheck statuses : (header.OverrideExisting ? AddResult.Failure : AddResult.KeyAlreadyExists)); response.Results.AddRange(addResults); return(response); }
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); }