예제 #1
0
        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);
        }
예제 #2
0
        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);
        }