Skip to content

Commit 7c8b987

Browse files
committed
Align behavior of grain storage providers when setting IGrainState<T> properties
1 parent abb4c26 commit 7c8b987

File tree

7 files changed

+159
-127
lines changed

7 files changed

+159
-127
lines changed

src/AWS/Orleans.Persistence.DynamoDB/Provider/DynamoDBGrainStorage.cs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ public class DynamoDBGrainStorage : IGrainStorage, ILifecycleParticipant<ISiloLi
3333

3434
private readonly DynamoDBStorageOptions options;
3535
private readonly ILogger logger;
36-
private readonly IServiceProvider serviceProvider;
37-
private readonly IActivatorProvider activatorProvider;
3836
private readonly string name;
3937

4038
private DynamoDBStorage storage;
@@ -45,14 +43,11 @@ public class DynamoDBGrainStorage : IGrainStorage, ILifecycleParticipant<ISiloLi
4543
public DynamoDBGrainStorage(
4644
string name,
4745
DynamoDBStorageOptions options,
48-
IServiceProvider serviceProvider,
4946
ILogger<DynamoDBGrainStorage> logger)
5047
{
5148
this.name = name;
5249
this.logger = logger;
5350
this.options = options;
54-
this.serviceProvider = serviceProvider;
55-
this.activatorProvider = this.serviceProvider.GetRequiredService<IActivatorProvider>();
5651
}
5752

5853
public void Participate(ISiloLifecycle lifecycle)
@@ -157,12 +152,8 @@ public async Task ReadStateAsync<T>(string grainType, GrainId grainId, IGrainSta
157152
}
158153
else
159154
{
160-
grainState.RecordExists = false;
161-
grainState.ETag = null;
162-
grainState.State = this.activatorProvider.GetActivator<T>().Create();
155+
ResetGrainState(grainState);
163156
}
164-
165-
// Else leave grainState in previous default condition
166157
}
167158

168159
/// <summary> Write state data function for this storage provider. </summary>
@@ -190,7 +181,7 @@ public async Task WriteStateAsync<T>(string grainType, GrainId grainId, IGrainSt
190181
this.logger.LogError(
191182
(int)ErrorCode.StorageProviderBase,
192183
exc,
193-
"Error Writing: GrainType={GrainType} Grainid={GrainId} ETag={ETag} to Table={TableName}",
184+
"Error Writing: GrainType={GrainType} GrainId={GrainId} ETag={ETag} to Table={TableName}",
194185
grainType,
195186
grainId,
196187
grainState.ETag,
@@ -298,12 +289,13 @@ public async Task ClearStateAsync<T>(string grainType, GrainId grainId, IGrainSt
298289
keys.Add(GRAIN_TYPE_PROPERTY_NAME, new AttributeValue(record.GrainType));
299290

300291
await this.storage.DeleteEntryAsync(this.options.TableName, keys).ConfigureAwait(false);
301-
grainState.ETag = null;
292+
ResetGrainState(grainState);
302293
}
303294
else
304295
{
305296
await WriteStateInternal(grainState, record, true);
306-
grainState.State = this.activatorProvider.GetActivator<T>().Create();
297+
grainState.State = Activator.CreateInstance<T>();
298+
grainState.RecordExists = false;
307299
}
308300
}
309301
catch (Exception exc)
@@ -381,6 +373,13 @@ internal void ConvertToStorageFormat(object grainState, GrainStateRecord entity)
381373
throw new ArgumentOutOfRangeException("GrainState.Size", msg);
382374
}
383375
}
376+
377+
private static void ResetGrainState<T>(IGrainState<T> grainState)
378+
{
379+
grainState.RecordExists = false;
380+
grainState.ETag = null;
381+
grainState.State = Activator.CreateInstance<T>();
382+
}
384383
}
385384

386385
public static class DynamoDBGrainStorageFactory

src/AdoNet/Orleans.Persistence.AdoNet/Storage/Provider/AdoNetGrainStorage.cs

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public static AdoNetGrainStorage Create(IServiceProvider services, string name)
6969
/// </para>
7070
/// </remarks>
7171
[DebuggerDisplay("Name = {Name}, ConnectionString = {Storage.ConnectionString}")]
72-
public class AdoNetGrainStorage: IGrainStorage, ILifecycleParticipant<ISiloLifecycle>
72+
public class AdoNetGrainStorage : IGrainStorage, ILifecycleParticipant<ISiloLifecycle>
7373
{
7474
public IGrainStorageSerializer Serializer { get; set; }
7575

@@ -137,13 +137,14 @@ public AdoNetGrainStorage(
137137
this.logger = logger;
138138
this.serviceId = clusterOptions.Value.ServiceId;
139139
this.Serializer = options.Value.GrainStorageSerializer;
140-
this.HashPicker = options.Value.HashPicker ?? new StorageHasherPicker(new[] { new OrleansDefaultHasher() });;
140+
this.HashPicker = options.Value.HashPicker ?? new StorageHasherPicker(new[] { new OrleansDefaultHasher() });
141141
}
142142

143143
public void Participate(ISiloLifecycle lifecycle)
144144
{
145145
lifecycle.Subscribe(OptionFormattingUtilities.Name<AdoNetGrainStorage>(this.name), this.options.InitStage, Init, Close);
146146
}
147+
147148
/// <summary>Clear state data function for this storage provider.</summary>
148149
/// <see cref="IGrainStorage.ClearStateAsync{T}"/>.
149150
public async Task ClearStateAsync<T>(string grainType, GrainId grainReference, IGrainState<T> grainState)
@@ -152,7 +153,7 @@ public async Task ClearStateAsync<T>(string grainType, GrainId grainReference, I
152153
//even if not as clear as when using explicitly checked parameters.
153154
var grainId = GrainIdAndExtensionAsString(grainReference);
154155
var baseGrainType = ExtractBaseClass(grainType);
155-
if(logger.IsEnabled(LogLevel.Trace))
156+
if (logger.IsEnabled(LogLevel.Trace))
156157
{
157158
logger.LogTrace(
158159
(int)RelationalStorageProviderCodes.RelationalProviderClearing,
@@ -182,7 +183,7 @@ public async Task ClearStateAsync<T>(string grainType, GrainId grainReference, I
182183
}, (selector, resultSetCount, token) => Task.FromResult(selector.GetValue(0).ToString()), cancellationToken: CancellationToken.None).ConfigureAwait(false));
183184
storageVersion = clearRecord.SingleOrDefault();
184185
}
185-
catch(Exception ex)
186+
catch (Exception ex)
186187
{
187188
logger.LogError(
188189
(int)RelationalStorageProviderCodes.RelationalProviderDeleteError,
@@ -198,15 +199,16 @@ public async Task ClearStateAsync<T>(string grainType, GrainId grainReference, I
198199

199200
const string OperationString = "ClearState";
200201
var inconsistentStateException = CheckVersionInconsistency(OperationString, serviceId, this.name, storageVersion, grainState.ETag, baseGrainType, grainId.ToString());
201-
if(inconsistentStateException != null)
202+
if (inconsistentStateException != null)
202203
{
203204
throw inconsistentStateException;
204205
}
205206

206207
//No errors found, the version of the state held by the grain can be updated and also the state.
207208
grainState.ETag = storageVersion;
208209
grainState.RecordExists = false;
209-
if(logger.IsEnabled(LogLevel.Trace))
210+
grainState.State = Activator.CreateInstance<T>();
211+
if (logger.IsEnabled(LogLevel.Trace))
210212
{
211213
logger.LogTrace(
212214
(int)RelationalStorageProviderCodes.RelationalProviderCleared,
@@ -273,19 +275,23 @@ public async Task ReadStateAsync<T>(string grainType, GrainId grainReference, IG
273275
},
274276
commandBehavior, CancellationToken.None).ConfigureAwait(false)).SingleOrDefault();
275277

276-
T state = readRecords != null ? (T) readRecords.Item1 : default;
278+
T state = readRecords != null ? (T)readRecords.Item1 : default;
277279
string etag = readRecords != null ? readRecords.Item2 : null;
278280
bool recordExists = readRecords != null;
279-
if(state == null)
281+
if (state == null)
280282
{
281-
logger.LogInformation(
282-
(int)RelationalStorageProviderCodes.RelationalProviderNoStateFound,
283-
"Null grain state read (default will be instantiated): ServiceId={ServiceId} ProviderName={Name} GrainType={BaseGrainType} GrainId={GrainId} ETag={ETag}.",
284-
serviceId,
285-
name,
286-
baseGrainType,
287-
grainId,
288-
grainState.ETag);
283+
if (logger.IsEnabled(LogLevel.Trace))
284+
{
285+
logger.LogTrace(
286+
(int)RelationalStorageProviderCodes.RelationalProviderNoStateFound,
287+
"Null grain state read (default will be instantiated): ServiceId={ServiceId} ProviderName={Name} GrainType={BaseGrainType} GrainId={GrainId} ETag={ETag}.",
288+
serviceId,
289+
name,
290+
baseGrainType,
291+
grainId,
292+
grainState.ETag);
293+
}
294+
289295
state = Activator.CreateInstance<T>();
290296
}
291297

@@ -304,7 +310,7 @@ public async Task ReadStateAsync<T>(string grainType, GrainId grainReference, IG
304310
grainState.ETag);
305311
}
306312
}
307-
catch(Exception ex)
313+
catch (Exception ex)
308314
{
309315
logger.LogError(
310316
(int)RelationalStorageProviderCodes.RelationalProviderReadError,
@@ -363,7 +369,7 @@ public async Task WriteStateAsync<T>(string grainType, GrainId grainReference, I
363369
{ return Task.FromResult(selector.GetNullableInt32("NewGrainStateVersion").ToString()); }, cancellationToken: CancellationToken.None).ConfigureAwait(false);
364370
storageVersion = writeRecord.SingleOrDefault();
365371
}
366-
catch(Exception ex)
372+
catch (Exception ex)
367373
{
368374
logger.LogError(
369375
(int)RelationalStorageProviderCodes.RelationalProviderWriteError,
@@ -379,7 +385,7 @@ public async Task WriteStateAsync<T>(string grainType, GrainId grainReference, I
379385

380386
const string OperationString = "WriteState";
381387
var inconsistentStateException = CheckVersionInconsistency(OperationString, serviceId, this.name, storageVersion, grainState.ETag, baseGrainType, grainId.ToString());
382-
if(inconsistentStateException != null)
388+
if (inconsistentStateException != null)
383389
{
384390
throw inconsistentStateException;
385391
}
@@ -424,7 +430,6 @@ private async Task Init(CancellationToken cancellationToken)
424430
ConfigUtilities.RedactConnectionStringInfo(Storage.ConnectionString));
425431
}
426432

427-
428433
/// <summary>
429434
/// Close this provider
430435
/// </summary>
@@ -433,7 +438,6 @@ private Task Close(CancellationToken token)
433438
return Task.CompletedTask;
434439
}
435440

436-
437441
/// <summary>
438442
/// Checks for version inconsistency as defined in the database scripts.
439443
/// </summary>
@@ -455,7 +459,7 @@ private static InconsistentStateException CheckVersionInconsistency(string opera
455459
//it means two grains were activated an the other one succeeded in writing its state.
456460
//
457461
//NOTE: the storage could return also the new and old ETag (Version), but currently it doesn't.
458-
if(storageVersion == grainVersion || storageVersion == string.Empty)
462+
if (storageVersion == grainVersion || storageVersion == string.Empty)
459463
{
460464
//TODO: Note that this error message should be canonical across back-ends.
461465
return new InconsistentStateException($"Version conflict ({operation}): ServiceId={serviceId} ProviderName={providerName} GrainType={normalizedGrainType} GrainId={grainId} ETag={grainVersion}.");

0 commit comments

Comments
 (0)