internal static void Serialize(object input, ISerializationContext context, Type expected) { GrainStateWithMetaDataAndETag <TView> instance = (GrainStateWithMetaDataAndETag <TView>)input; SerializationManager.SerializeInner(instance.ETag, context, typeof(string)); SerializationManager.SerializeInner(instance.State, context, typeof(TView)); SerializationManager.SerializeInner(instance.GlobalVersion, context, typeof(int)); SerializationManager.SerializeInner(instance.WriteVector, context, typeof(string)); }
internal static object DeepCopier(object original, ICopyContext context) { GrainStateWithMetaDataAndETag <TView> instance = (GrainStateWithMetaDataAndETag <TView>)original; string etag = (string)SerializationManager.DeepCopyInner(instance.ETag, context); TView state = (TView)SerializationManager.DeepCopyInner(instance.State, context); int globalVersion = (int)SerializationManager.DeepCopyInner(instance.GlobalVersion, context); string writeVector = (string)SerializationManager.DeepCopyInner(instance.WriteVector, context); return(new GrainStateWithMetaDataAndETag <TView>(etag, state, globalVersion, writeVector)); }
/// <inheritdoc/> protected override async Task ReadAsync() { enter_operation("ReadAsync"); while (true) { try { // for manual testing //await Task.Delay(5000); var readState = new GrainStateWithMetaDataAndETag <TLogView>(); await globalGrainStorage.ReadStateAsync(grainTypeName, Services.GrainReference, readState); GlobalStateCache = readState; Services.Log(LogLevel.Debug, "read success {0}", GlobalStateCache); LastPrimaryIssue.Resolve(Host, Services); break; // successful } catch (Exception e) { LastPrimaryIssue.Record(new ReadFromStateStorageFailed() { Exception = e }, Host, Services); } Services.Log(LogLevel.Debug, "read failed {0}", LastPrimaryIssue); await LastPrimaryIssue.DelayBeforeRetry(); } exit_operation("ReadAsync"); }
/// <inheritdoc/> protected override void InitializeConfirmedView(TLogView initialstate) { GlobalStateCache = new GrainStateWithMetaDataAndETag <TLogView>(initialstate); }
/// <inheritdoc/> protected override async Task <int> WriteAsync() { enter_operation("WriteAsync"); var state = CopyTentativeState(); var updates = GetCurrentBatchOfUpdates(); bool batchsuccessfullywritten = false; var nextglobalstate = new GrainStateWithMetaDataAndETag <TLogView>(state); nextglobalstate.StateAndMetaData.WriteVector = GlobalStateCache.StateAndMetaData.WriteVector; nextglobalstate.StateAndMetaData.GlobalVersion = GlobalStateCache.StateAndMetaData.GlobalVersion + updates.Length; nextglobalstate.ETag = GlobalStateCache.ETag; var writebit = nextglobalstate.StateAndMetaData.FlipBit(Services.MyClusterId); try { // for manual testing //await Task.Delay(5000); await globalStorageProvider.WriteStateAsync(grainTypeName, Services.GrainReference, nextglobalstate); batchsuccessfullywritten = true; GlobalStateCache = nextglobalstate; Services.Log(Severity.Verbose, "write ({0} updates) success {1}", updates.Length, GlobalStateCache); LastPrimaryIssue.Resolve(Host, Services); } catch (Exception e) { LastPrimaryIssue.Record(new UpdateStateStorageFailed() { Exception = e }, Host, Services); } if (!batchsuccessfullywritten) { Services.Log(Severity.Verbose, "write apparently failed {0} {1}", nextglobalstate, LastPrimaryIssue); while (true) // be stubborn until we can read what is there { await LastPrimaryIssue.DelayBeforeRetry(); try { await globalStorageProvider.ReadStateAsync(grainTypeName, Services.GrainReference, GlobalStateCache); Services.Log(Severity.Verbose, "read success {0}", GlobalStateCache); LastPrimaryIssue.Resolve(Host, Services); break; } catch (Exception e) { LastPrimaryIssue.Record(new ReadFromStateStorageFailed() { Exception = e }, Host, Services); } Services.Log(Severity.Verbose, "read failed {0}", LastPrimaryIssue); } // check if last apparently failed write was in fact successful if (writebit == GlobalStateCache.StateAndMetaData.GetBit(Services.MyClusterId)) { GlobalStateCache = nextglobalstate; Services.Log(Severity.Verbose, "last write ({0} updates) was actually a success {1}", updates.Length, GlobalStateCache); batchsuccessfullywritten = true; } } // broadcast notifications to all other clusters if (batchsuccessfullywritten) { BroadcastNotification(new UpdateNotificationMessage() { Version = GlobalStateCache.StateAndMetaData.GlobalVersion, Updates = updates.Select(se => se.Entry).ToList(), Origin = Services.MyClusterId, ETag = GlobalStateCache.ETag }); } exit_operation("WriteAsync"); if (!batchsuccessfullywritten) { return(0); } return(updates.Length); }