1616using  Orleans . Configuration . Overrides ; 
1717using  Orleans . Configuration ; 
1818using  Orleans . Runtime . Configuration ; 
19+ using  Orleans . Serialization . Serializers ; 
1920
2021namespace  Orleans . Storage 
2122{ 
@@ -69,7 +70,7 @@ public static AdoNetGrainStorage Create(IServiceProvider services, string name)
6970    /// </para> 
7071    /// </remarks> 
7172    [ DebuggerDisplay ( "Name = {Name}, ConnectionString = {Storage.ConnectionString}" ) ] 
72-     public  class  AdoNetGrainStorage :  IGrainStorage ,  ILifecycleParticipant < ISiloLifecycle > 
73+     public  class  AdoNetGrainStorage   :  IGrainStorage ,  ILifecycleParticipant < ISiloLifecycle > 
7374    { 
7475        public  IGrainStorageSerializer  Serializer  {  get ;  set ;  } 
7576
@@ -90,7 +91,7 @@ public class AdoNetGrainStorage: IGrainStorage, ILifecycleParticipant<ISiloLifec
9091        /// The Service ID for which this relational provider is used. 
9192        /// </summary> 
9293        private  readonly  string  serviceId ; 
93- 
94+          private   readonly   IActivatorProvider   _activatorProvider ; 
9495        private  readonly  ILogger  logger ; 
9596
9697        /// <summary> 
@@ -121,29 +122,29 @@ public class AdoNetGrainStorage: IGrainStorage, ILifecycleParticipant<ISiloLifec
121122        public  IStorageHasherPicker  HashPicker  {  get ;  set ;  } 
122123
123124        private  readonly  AdoNetGrainStorageOptions  options ; 
124-         private  readonly  IProviderRuntime  providerRuntime ; 
125125        private  readonly  string  name ; 
126126
127127        public  AdoNetGrainStorage ( 
128+             IActivatorProvider  activatorProvider , 
128129            ILogger < AdoNetGrainStorage >  logger , 
129-             IProviderRuntime  providerRuntime , 
130130            IOptions < AdoNetGrainStorageOptions >  options , 
131131            IOptions < ClusterOptions >  clusterOptions , 
132132            string  name ) 
133133        { 
134134            this . options  =  options . Value ; 
135-             this . providerRuntime  =  providerRuntime ; 
136135            this . name  =  name ; 
136+             _activatorProvider  =  activatorProvider ; 
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 , 
@@ -164,6 +165,15 @@ public async Task ClearStateAsync<T>(string grainType, GrainId grainReference, I
164165                    grainState . ETag ) ; 
165166            } 
166167
168+             if  ( ! grainState . RecordExists ) 
169+             { 
170+                 await  ReadStateAsync ( grainType ,  grainReference ,  grainState ) . ConfigureAwait ( false ) ; 
171+                 if  ( ! grainState . RecordExists ) 
172+                 { 
173+                     return ; 
174+                 } 
175+             } 
176+ 
167177            string  storageVersion  =  null ; 
168178            try 
169179            { 
@@ -182,7 +192,7 @@ public async Task ClearStateAsync<T>(string grainType, GrainId grainReference, I
182192                } ,  ( selector ,  resultSetCount ,  token )  =>  Task . FromResult ( selector . GetValue ( 0 ) . ToString ( ) ) ,  cancellationToken :  CancellationToken . None ) . ConfigureAwait ( false ) ) ; 
183193                storageVersion  =  clearRecord . SingleOrDefault ( ) ; 
184194            } 
185-             catch ( Exception  ex ) 
195+             catch   ( Exception  ex ) 
186196            { 
187197                logger . LogError ( 
188198                    ( int ) RelationalStorageProviderCodes . RelationalProviderDeleteError , 
@@ -198,15 +208,16 @@ public async Task ClearStateAsync<T>(string grainType, GrainId grainReference, I
198208
199209            const  string  OperationString  =  "ClearState" ; 
200210            var  inconsistentStateException  =  CheckVersionInconsistency ( OperationString ,  serviceId ,  this . name ,  storageVersion ,  grainState . ETag ,  baseGrainType ,  grainId . ToString ( ) ) ; 
201-             if ( inconsistentStateException  !=  null ) 
211+             if   ( inconsistentStateException  !=  null ) 
202212            { 
203213                throw  inconsistentStateException ; 
204214            } 
205215
206216            //No errors found, the version of the state held by the grain can be updated and also the state. 
207217            grainState . ETag  =  storageVersion ; 
208218            grainState . RecordExists  =  false ; 
209-             if ( logger . IsEnabled ( LogLevel . Trace ) ) 
219+             grainState . State  =  CreateInstance < T > ( ) ; 
220+             if  ( logger . IsEnabled ( LogLevel . Trace ) ) 
210221            { 
211222                logger . LogTrace ( 
212223                    ( int ) RelationalStorageProviderCodes . RelationalProviderCleared , 
@@ -273,20 +284,24 @@ public async Task ReadStateAsync<T>(string grainType, GrainId grainReference, IG
273284                    } , 
274285                    commandBehavior ,  CancellationToken . None ) . ConfigureAwait ( false ) ) . SingleOrDefault ( ) ; 
275286
276-                 T  state  =  readRecords  !=  null  ?  ( T )   readRecords . Item1  :  default ; 
287+                 T  state  =  readRecords  !=  null  ?  ( T ) readRecords . Item1  :  default ; 
277288                string  etag  =  readRecords  !=  null  ?  readRecords . Item2  :  null ; 
278289                bool  recordExists  =  readRecords  !=  null ; 
279-                 if ( state  ==  null ) 
290+                 if   ( state  ==  null ) 
280291                { 
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 ) ; 
289-                     state  =  Activator . CreateInstance < T > ( ) ; 
292+                     if  ( logger . IsEnabled ( LogLevel . Trace ) ) 
293+                     { 
294+                         logger . LogTrace ( 
295+                             ( int ) RelationalStorageProviderCodes . RelationalProviderNoStateFound , 
296+                             "Null grain state read (default will be instantiated): ServiceId={ServiceId} ProviderName={Name} GrainType={BaseGrainType} GrainId={GrainId} ETag={ETag}." , 
297+                             serviceId , 
298+                             name , 
299+                             baseGrainType , 
300+                             grainId , 
301+                             grainState . ETag ) ; 
302+                     } 
303+ 
304+                     state  =  CreateInstance < T > ( ) ; 
290305                } 
291306
292307                grainState . State  =  state ; 
@@ -304,7 +319,7 @@ public async Task ReadStateAsync<T>(string grainType, GrainId grainReference, IG
304319                        grainState . ETag ) ; 
305320                } 
306321            } 
307-             catch ( Exception  ex ) 
322+             catch   ( Exception  ex ) 
308323            { 
309324                logger . LogError ( 
310325                    ( int ) RelationalStorageProviderCodes . RelationalProviderReadError , 
@@ -363,7 +378,7 @@ public async Task WriteStateAsync<T>(string grainType, GrainId grainReference, I
363378                {  return  Task . FromResult ( selector . GetNullableInt32 ( "NewGrainStateVersion" ) . ToString ( ) ) ;  } ,  cancellationToken :  CancellationToken . None ) . ConfigureAwait ( false ) ; 
364379                storageVersion  =  writeRecord . SingleOrDefault ( ) ; 
365380            } 
366-             catch ( Exception  ex ) 
381+             catch   ( Exception  ex ) 
367382            { 
368383                logger . LogError ( 
369384                    ( int ) RelationalStorageProviderCodes . RelationalProviderWriteError , 
@@ -379,7 +394,7 @@ public async Task WriteStateAsync<T>(string grainType, GrainId grainReference, I
379394
380395            const  string  OperationString  =  "WriteState" ; 
381396            var  inconsistentStateException  =  CheckVersionInconsistency ( OperationString ,  serviceId ,  this . name ,  storageVersion ,  grainState . ETag ,  baseGrainType ,  grainId . ToString ( ) ) ; 
382-             if ( inconsistentStateException  !=  null ) 
397+             if   ( inconsistentStateException  !=  null ) 
383398            { 
384399                throw  inconsistentStateException ; 
385400            } 
@@ -424,7 +439,6 @@ private async Task Init(CancellationToken cancellationToken)
424439                ConfigUtilities . RedactConnectionStringInfo ( Storage . ConnectionString ) ) ; 
425440        } 
426441
427- 
428442        /// <summary> 
429443        /// Close this provider 
430444        /// </summary> 
@@ -433,7 +447,6 @@ private Task Close(CancellationToken token)
433447            return  Task . CompletedTask ; 
434448        } 
435449
436- 
437450        /// <summary> 
438451        /// Checks for version inconsistency as defined in the database scripts. 
439452        /// </summary> 
@@ -455,7 +468,7 @@ private static InconsistentStateException CheckVersionInconsistency(string opera
455468            //it means two grains were activated an the other one succeeded in writing its state. 
456469            // 
457470            //NOTE: the storage could return also the new and old ETag (Version), but currently it doesn't. 
458-             if ( storageVersion  ==  grainVersion  ||  storageVersion  ==  string . Empty ) 
471+             if   ( storageVersion  ==  grainVersion  ||  storageVersion  ==  string . Empty ) 
459472            { 
460473                //TODO: Note that this error message should be canonical across back-ends. 
461474                return  new  InconsistentStateException ( $ "Version conflict ({ operation } ): ServiceId={ serviceId }  ProviderName={ providerName }  GrainType={ normalizedGrainType }  GrainId={ grainId }  ETag={ grainVersion } .") ; 
@@ -545,5 +558,7 @@ int GetGenericArity(string input)
545558                return  0 ; 
546559            } 
547560        } 
561+ 
562+         private  T  CreateInstance < T > ( )  =>  _activatorProvider . GetActivator < T > ( ) . Create ( ) ; 
548563    } 
549564} 
0 commit comments