コード例 #1
0
        private bool DeleteInstanceInternal(IComparable instanceId, bool replicate, long evictionVersion)
        {
            Requires.Argument("instanceId", instanceId).NotNull();

            StatefulServiceExecutionContext executionContext = StatefulServiceExecutionContext.Current as StatefulServiceExecutionContext;

            if (executionContext == null || executionContext.Partition == null)
            {
                throw new InvalidOperationException("Program instance cannot be obtained outside context of a partition. Please ensure that StatefulServiceReplicaT.Invoke is called.");
            }

            StatefulProgramInstance instance = null;
            ItemCollection <IComparable, StatefulProgramInstance> instances;

            using (this.instanceManager.GetInstances(LockPermission.Write, out instances))
            {
                if (instances.Contains(instanceId))
                {
                    instance = (StatefulProgramInstance)instances[instanceId];
                    if (evictionVersion != -2 && !instance.CanEvict(evictionVersion))
                    {
                        return(false);
                    }

                    instances.Remove(instanceId);
                    ((IDisposable)instance).Dispose();
                }
            }

            if (instance != null)
            {
                if (replicate)
                {
                    Replicable <StatefulProgramInstance> replicable = new Replicable <StatefulProgramInstance>(instance.Id.ToString(), instance);
                    ReplicationScope replicationScope = new ReplicationScope(new Replicable[] { replicable }, ReplicationOperationType.Evict);
                    replicationScope.ReplicateAsync().ContinueWith(
                        task =>
                    {
                        ReplicationResult result = task.IsFaulted ? ReplicationResult.Failed : task.Result;
                        if (result != ReplicationResult.Success)
                        {
                            AppTrace.TraceMsg(TraceLogEventType.Warning, "StatefulServiceReplicaT.DeleteInstanceInternal", "Replication call to dispose the instance with id {0} failed.", instance.Id);
                        }
                    },
                        TaskContinuationOptions.ExecuteSynchronously);
                }

                return(true);
            }
            else
            {
                return(false);
            }
        }
コード例 #2
0
        protected sealed override IEnumerable <Replicable> OnApplyReplicationOperation(StatefulServiceExecutionContext executionContext, ReplicationOperation replicationOperation)
        {
            if (this.IsDisposed)
            {
                AppTrace.TraceMsg(TraceLogEventType.Information, "StatefulServiceReplicaT.OnApplyReplicationOperation", "OnApplyReplicationOperation called after service was disposed");
                return(Enumerable.Empty <Replicable>());
            }

            if (replicationOperation.Type == ReplicationOperationType.Replicate || replicationOperation.Type == ReplicationOperationType.Copy)
            {
                List <Replicable> replicablesToCommit = new List <Replicable>();

                ItemCollection <IComparable, StatefulProgramInstance> instances;
                using (this.instanceManager.GetInstances(LockPermission.Write, out instances))
                {
                    if (replicationOperation.Type == ReplicationOperationType.Copy)
                    {
                        instances.Clear();
                    }

                    int count = replicationOperation.Replicables.Count();

                    //// Bug#221476
                    //// Debug.Assert(count <= 1, string.Format(CultureInfo.InvariantCulture, "Unexpected number of replicables {0}", count));

                    Replicable <StatefulProgramInstance> replicableToApply = (Replicable <StatefulProgramInstance>)replicationOperation.Replicables.FirstOrDefault();
                    if (replicableToApply == null)
                    {
                        return(replicablesToCommit);
                    }

                    StatefulProgramInstance instance = (StatefulProgramInstance)this.GetOrCreateInstance(replicableToApply.Value.Id, Type.GetType(replicableToApply.Value.TypeName), replicableToApply.Value.InitializationParams);
                    if (instance != null)
                    {
                        instance.SetContextInstanceId();
                        ItemCollection <string, Replicable> replicables;
                        using (instance.GetReplicables(LockPermission.Write, out replicables))
                        {
                            if (replicationOperation.Type == ReplicationOperationType.Copy)
                            {
                                // Overwrite the existing replicables
                                replicables.Fill(replicableToApply.Value.DataContractReplicables);
                                replicablesToCommit.AddRange(replicables);
                            }
                            else if (replicableToApply.IsDisposed)
                            {
                                /// If this ProgramInstance was disposed, then dispose all associated Replicables and add them
                                /// to replicablesToCommit so that the persistence logic can pick it up and delete from the store
                                /// if required.
                                ItemCollection <string, Replicable> instanceReplicables;
                                using (instance.GetReplicables(LockPermission.Read, out instanceReplicables))
                                {
                                    foreach (Replicable replicable in instanceReplicables)
                                    {
                                        replicable.Dispose();
                                        replicablesToCommit.Add(replicable);
                                    }
                                }

                                this.DeleteInstanceInternal(instance.Id, false, -2);
                            }
                            else
                            {
                                foreach (Replicable replicable in replicableToApply.Value.DataContractReplicables)
                                {
                                    if (!replicable.IsDisposed)
                                    {
                                        if (replicables.Contains(replicable.Name))
                                        {
                                            // TODO: Need setitem support on ItemCollection
                                            Replicable existingReplicable = replicables[replicable.Name];
                                            if (existingReplicable.SequenceNumber <= replicable.SequenceNumber)
                                            {
                                                replicables.Remove(replicable.Name);
                                                replicables.Add(replicable);
                                            }
                                        }
                                        else
                                        {
                                            replicables.Add(replicable);
                                        }

                                        replicablesToCommit.Add(replicable);
                                    }
                                    else
                                    {
                                        replicables.Remove(replicable.Name);
                                    }
                                }
                            }
                        }

                        instance.SetContextInstanceId(replicablesToCommit);
                    }
                }

                return(replicablesToCommit);
            }
            else if (replicationOperation.Type == ReplicationOperationType.Evict)
            {
                int count = replicationOperation.Replicables.Count();
                Debug.Assert(count <= 1, string.Format(CultureInfo.InvariantCulture, "Unexpected number of replicables {0}", count));
                Replicable <StatefulProgramInstance> replicable = (Replicable <StatefulProgramInstance>)replicationOperation.Replicables.FirstOrDefault();
                if (replicable != null)
                {
                    ItemCollection <IComparable, StatefulProgramInstance> instances;
                    using (this.instanceManager.GetInstances(LockPermission.Write, out instances))
                    {
                        foreach (Replicable <StatefulProgramInstance> instance in replicationOperation.Replicables)
                        {
                            this.DeleteInstanceInternal(instance.Value.Id, false, -2);
                        }
                    }
                }

                return(replicationOperation.Replicables);
            }

            return(base.OnApplyReplicationOperation(executionContext, replicationOperation));
        }
コード例 #3
0
        protected internal sealed override IEnumerable <Replicable> ReplicationOperationComplete(StatefulServiceExecutionContext executionContext, ReplicationResult result, ReplicationOperation replicationOperation)
        {
            if (this.IsDisposed)
            {
                AppTrace.TraceMsg(TraceLogEventType.Information, "StatefulServiceReplicaT.ReplicationOperationComplete", "ReplicationOperationComplete called after service was disposed");
                return(Enumerable.Empty <Replicable>());
            }

            StatefulProgramInstance instance = null;
            Replicable <StatefulProgramInstance> replicableToCommit = replicationOperation.Replicables.FirstOrDefault() as Replicable <StatefulProgramInstance>;

            if (replicableToCommit != null)
            {
                instance = this.instanceManager.GetInstance(replicableToCommit.Value.Id) as StatefulProgramInstance;
                if (instance != null)
                {
                    instance.SetContextInstanceId();
                }
                else if (replicableToCommit.Value != null)
                {
                    Debug.Assert(replicationOperation.Type == ReplicationOperationType.Evict, "Unexpected operation type");
                    replicableToCommit.Value.SetContextInstanceId();
                }
                else
                {
                    Debug.Assert(false, "replicableToCommit.Value is null");
                }
            }

            AppTrace.TraceMsg(
                TraceLogEventType.Information,
                "StatefulComponent.ReplicationOperationComplete",
                "replicationOperation.Type={0}, result={1}, replicables.Count={2}, replicableToCommit={3}, programInstance={4}",
                replicationOperation.Type,
                result,
                replicationOperation.Replicables.Count(),
                replicableToCommit != null ? replicableToCommit.Name : "Null",
                instance != null ? instance.Id : "Null");

            IEnumerable <Replicable> replicablesToCommit = null;

            if (replicationOperation.Type == ReplicationOperationType.Replicate)
            {
                if (result == ReplicationResult.Success)
                {
                    List <Replicable> changes = new List <Replicable>();

                    if (replicableToCommit.IsDisposed)
                    {
                        foreach (Replicable replicable in replicableToCommit.Value.DataContractReplicables)
                        {
                            changes.Add(replicable);
                        }
                    }
                    else
                    {
                        ItemCollection <string, Replicable> replicables;
                        using (instance.GetReplicables(LockPermission.Write, out replicables))
                        {
                            foreach (Replicable replicable in replicableToCommit.Value.DataContractReplicables)
                            {
                                if (replicables.Contains(replicable.Name))
                                {
                                    replicables.Remove(replicable.Name);
                                    replicables.Add(replicable);
                                }
                                else
                                {
                                    replicables.Add(replicable);
                                }

                                changes.Add(replicable);
                            }
                        }
                    }

                    replicablesToCommit = changes;
                }
                else
                {
                    if (instance != null)
                    {
                        AppTrace.TraceMsg(TraceLogEventType.Error, "StatefulServiceReplicaT.ReplicationOperationComplete", "Recycling StatefulProgramInstance with id '{0}'", instance.Id);
                        instance.RecycleInstance();
                    }

                    replicablesToCommit = base.ReplicationOperationComplete(executionContext, result, replicationOperation);
                }
            }

            if (replicablesToCommit == null)
            {
                replicablesToCommit = base.ReplicationOperationComplete(executionContext, result, replicationOperation);
            }

            return(replicablesToCommit);
        }