示例#1
0
        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));
        }
示例#2
0
        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");
        }
示例#4
0
 /// <inheritdoc/>
 protected override void InitializeConfirmedView(TLogView initialstate)
 {
     GlobalStateCache = new GrainStateWithMetaDataAndETag <TLogView>(initialstate);
 }
示例#5
0
        /// <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);
        }