Exemplo n.º 1
0
        public async Task <bool> UpdateRow(MembershipEntry entry, string etag, TableVersion tableVersion)
        {
            try
            {
                if (logger.IsEnabled(LogLevel.Debug))
                {
                    logger.Debug("UpdateRow entry = {0}, etag = {1}", entry.ToFullString(), etag);
                }
                var siloEntry   = Convert(entry);
                int currentEtag = 0;
                if (!int.TryParse(etag, out currentEtag))
                {
                    logger.Warn(ErrorCode.MembershipBase,
                                $"Update failed. Invalid ETag value. Will retry. Entry {entry.ToFullString()}, eTag {etag}");
                    return(false);
                }

                siloEntry.ETag = currentEtag + 1;

                bool result;

                try
                {
                    var conditionalValues = new Dictionary <string, AttributeValue> {
                        { CURRENT_ETAG_ALIAS, new AttributeValue {
                              N = etag
                          } }
                    };
                    var etagConditionalExpression = $"{SiloInstanceRecord.ETAG_PROPERTY_NAME} = {CURRENT_ETAG_ALIAS}";
                    await storage.UpsertEntryAsync(TABLE_NAME_DEFAULT_VALUE, siloEntry.GetKeys(),
                                                   siloEntry.GetFields(), etagConditionalExpression, conditionalValues);

                    result = true;
                }
                catch (ConditionalCheckFailedException)
                {
                    result = false;
                    logger.Warn(ErrorCode.MembershipBase,
                                $"Update failed due to contention on the table. Will retry. Entry {entry.ToFullString()}, eTag {etag}");
                }

                return(result);
            }
            catch (Exception exc)
            {
                logger.Warn(ErrorCode.MembershipBase,
                            $"Intermediate error updating entry {entry.ToFullString()} to the table {TABLE_NAME_DEFAULT_VALUE}.", exc);
                throw;
            }
        }
Exemplo n.º 2
0
        private async Task WriteStateInternal(IGrainState grainState, GrainStateRecord record, bool clear = false)
        {
            var fields = new Dictionary <string, AttributeValue>();

            if (record.BinaryState != null && record.BinaryState.Length > 0)
            {
                fields.Add(BINARY_STATE_PROPERTY_NAME, new AttributeValue {
                    B = new MemoryStream(record.BinaryState)
                });
            }
            else if (!string.IsNullOrWhiteSpace(record.StringState))
            {
                fields.Add(STRING_STATE_PROPERTY_NAME, new AttributeValue(record.StringState));
            }

            int newEtag = 0;

            if (clear)
            {
                fields.Add(GRAIN_REFERENCE_PROPERTY_NAME, new AttributeValue(record.GrainReference));
                fields.Add(GRAIN_TYPE_PROPERTY_NAME, new AttributeValue(record.GrainType));

                int currentEtag = 0;
                int.TryParse(grainState.ETag, out currentEtag);
                newEtag = currentEtag;
                fields.Add(ETAG_PROPERTY_NAME, new AttributeValue {
                    N = newEtag++.ToString()
                });

                await storage.PutEntryAsync(tableName, fields).ConfigureAwait(false);
            }
            else if (string.IsNullOrWhiteSpace(grainState.ETag))
            {
                fields.Add(GRAIN_REFERENCE_PROPERTY_NAME, new AttributeValue(record.GrainReference));
                fields.Add(GRAIN_TYPE_PROPERTY_NAME, new AttributeValue(record.GrainType));
                fields.Add(ETAG_PROPERTY_NAME, new AttributeValue {
                    N = "0"
                });

                var expression = $"attribute_not_exists({GRAIN_REFERENCE_PROPERTY_NAME}) AND attribute_not_exists({GRAIN_TYPE_PROPERTY_NAME})";
                await storage.PutEntryAsync(tableName, fields, expression).ConfigureAwait(false);
            }
            else
            {
                var keys = new Dictionary <string, AttributeValue>();
                keys.Add(GRAIN_REFERENCE_PROPERTY_NAME, new AttributeValue(record.GrainReference));
                keys.Add(GRAIN_TYPE_PROPERTY_NAME, new AttributeValue(record.GrainType));

                int currentEtag = 0;
                int.TryParse(grainState.ETag, out currentEtag);
                newEtag = currentEtag;
                newEtag++;
                fields.Add(ETAG_PROPERTY_NAME, new AttributeValue {
                    N = newEtag.ToString()
                });

                var conditionalValues = new Dictionary <string, AttributeValue> {
                    { CURRENT_ETAG_ALIAS, new AttributeValue {
                          N = currentEtag.ToString()
                      } }
                };
                var expression = $"{ETAG_PROPERTY_NAME} = {CURRENT_ETAG_ALIAS}";
                await storage.UpsertEntryAsync(tableName, keys, fields, expression, conditionalValues).ConfigureAwait(false);
            }

            grainState.ETag = newEtag.ToString();
        }