Ejemplo n.º 1
0
        public async Task <ValueRecord> AddOrUpdate(
            KeyRecord key,
            Func <KeyRecord, Task <ValueRecord> > addFactory,
            Func <KeyRecord, ValueRecord, Task <ValueRecord> > updateFactory,
            CancellationToken token)
        {
            var strategy = options.UpsertRetry;

            var attempt = 1;

            while (true)
            {
                logger.LogDebug("Storage.AddOrUpdate({KeyId}): {Attempt} begins.", key.Id, attempt);

                ValueRecord newValue;
                if (await TryGet(key, token) is not Some <ValueRecord>(var currentValue))
                {
                    var addedKey = new MongoKeyRecord(key.Id, key.Type, key.Content);
                    await InsertOne(keyCollection, addedKey, token);

                    currentValue = null;
                    newValue     = await addFactory(key);

                    logger.LogDebug("Storage.AddOrUpdate({KeyId}): {Attempt} adding value.", key.Id, attempt);
                }
Ejemplo n.º 2
0
        public async Task <ValueRecord> AddOrGet(
            KeyRecord key,
            Func <KeyRecord, Task <ValueRecord> > addFactory,
            CancellationToken token)
        {
            var strategy = options.UpsertRetry;

            var attempt = 1;

            while (true)
            {
                logger.LogDebug("Storage.AddOrGet({KeyId}): {Attempt} begins.", key.Id, attempt);

                if (await TryGet(key, token) is Some <ValueRecord>(var currentValue))
                {
                    logger.LogDebug("Storage.AddOrGet({KeyId}): {Attempt} got value.", key.Id, attempt);
                    return(currentValue);
                }

                var addedKey = new MongoKeyRecord(key.Id, key.Type, key.Content);
                await InsertOne(keyCollection, addedKey, token);

                var newValue = await addFactory(key);

                if (await AddValue(key, currentValue: null, newValue, token) is Some <ValueRecord>(var added))
                {
                    logger.LogDebug("Storage.AddOrGet({KeyId}): {Attempt} added initial version.", key.Id, attempt);
                    return(added);
                }

                attempt++;
                if (!strategy.CanRetry(attempt))
                {
                    logger.LogDebug("Storage.AddOrGet({KeyId}): {Attempt} won't proceed.", key.Id, attempt);
                    break;
                }

                await Task.Delay(strategy.DelayTime(attempt), token);
            }

            throw new StorageConcurrencyException();
        }