Пример #1
0
        private Dictionary <string, IDictionary <IIndexableGrain, IList <IMemberUpdate> > > PopulateUpdatesToIndexes(
            IndexWorkflowRecordNode currentWorkflow, Dictionary <IIndexableGrain, HashSet <Guid> > grainsToActiveWorkflows)
        {
            var  updatesToIndexes = new Dictionary <string, IDictionary <IIndexableGrain, IList <IMemberUpdate> > >();
            bool faultTolerant    = IsFaultTolerant;

            for (; !currentWorkflow.IsPunctuation; currentWorkflow = currentWorkflow.Next)
            {
                IndexWorkflowRecord workflowRec = currentWorkflow.WorkflowRecord;
                IIndexableGrain     g           = workflowRec.Grain;
                bool existsInActiveWorkflows    = faultTolerant && grainsToActiveWorkflows.TryGetValue(g, out HashSet <Guid> activeWorkflowRecs) &&
                                                  activeWorkflowRecs.Contains(workflowRec.WorkflowId);

                foreach (var(indexName, updt) in currentWorkflow.WorkflowRecord.MemberUpdates.Where(kvp => kvp.Value.OperationType != IndexOperationType.None))
                {
                    var updatesByGrain  = updatesToIndexes.GetOrAdd(indexName, () => new Dictionary <IIndexableGrain, IList <IMemberUpdate> >());
                    var updatesForGrain = updatesByGrain.GetOrAdd(g, () => new List <IMemberUpdate>());

                    if (!faultTolerant || existsInActiveWorkflows)
                    {
                        updatesForGrain.Add(updt);
                    }
                    else if (GrainIndexes[indexName].MetaData.IsUniqueIndex)
                    {
                        // If the workflow record does not exist in the set of active workflows and the index is fault-tolerant,
                        // enqueue a reversal (undo) to any possible remaining tentative updates to unique indexes.
                        updatesForGrain.Add(new MemberUpdateReverseTentative(updt));
                    }
                }
            }
            return(updatesToIndexes);
        }
Пример #2
0
 private void RemoveFromQueueNonPersistent(IndexWorkflowRecord newWorkflow)
 {
     for (var current = queueState.State.WorkflowRecordsHead; current != null; current = current.Next)
     {
         if (newWorkflow.Equals(current.WorkflowRecord))
         {
             current.Remove(ref queueState.State.WorkflowRecordsHead, ref _workflowRecordsTail);
             return;
         }
     }
 }
Пример #3
0
        private void PopulateUpdatesToIndexes(IndexWorkflowRecordNode currentWorkflow, Dictionary <string, IDictionary <IIndexableGrain, IList <IMemberUpdate> > > updatesToIndexes, Dictionary <IIndexableGrain, HashSet <Guid> > grainsToActiveWorkflows)
        {
            bool faultTolerant = IsFaultTolerant;

            while (!currentWorkflow.IsPunctuation())
            {
                IndexWorkflowRecord workflowRec = currentWorkflow.WorkflowRecord;
                IIndexableGrain     g           = workflowRec.Grain;
                bool existsInActiveWorkflows    = false;
                if (faultTolerant)
                {
                    HashSet <Guid> activeWorkflowRecs = null;
                    if (grainsToActiveWorkflows.TryGetValue(g, out activeWorkflowRecs))
                    {
                        if (activeWorkflowRecs.Contains(workflowRec.WorkflowId))
                        {
                            existsInActiveWorkflows = true;
                        }
                    }
                }

                foreach (var updates in currentWorkflow.WorkflowRecord.MemberUpdates)
                {
                    IMemberUpdate updt = updates.Value;
                    if (updt.GetOperationType() != IndexOperationType.None)
                    {
                        string index          = updates.Key;
                        var    updatesToIndex = updatesToIndexes[index];
                        IList <IMemberUpdate> updatesList;
                        if (!updatesToIndex.TryGetValue(g, out updatesList))
                        {
                            updatesList = new List <IMemberUpdate>();
                            updatesToIndex.Add(g, updatesList);
                        }

                        if (!faultTolerant || existsInActiveWorkflows)
                        {
                            updatesList.Add(updt);
                        }
                        //if the workflow record does not exist in the list of active work-flows
                        //and the index is fault-tolerant, we should make sure that tentative updates
                        //to unique indexes are undone
                        else if (((IndexMetaData)Indexes[index].Item2).IsUniqueIndex())
                        {
                            //reverse a possible remaining tentative record from the index
                            updatesList.Add(new MemberUpdateReverseTentative(updt));
                        }
                    }
                }
                currentWorkflow = currentWorkflow.Next;
            }
        }
Пример #4
0
        public Task AddToQueue(Immutable <IndexWorkflowRecord> workflow)
        {
            IndexWorkflowRecord newWorkflow = workflow.Value;

            AddToQueueNonPersistent(newWorkflow);

            InitiateWorkerThread();
            if (IsFaultTolerant)
            {
                return(PersistState());
            }
            return(TaskDone.Done);
        }
Пример #5
0
        private void RemoveFromQueueNonPersistent(IndexWorkflowRecord newWorkflow)
        {
            IndexWorkflowRecordNode current = State.State.WorkflowRecordsHead;

            while (current != null)
            {
                if (newWorkflow.Equals(current.WorkflowRecord))
                {
                    current.Remove(ref State.State.WorkflowRecordsHead, ref _workflowRecordsTail);
                    return;
                }
                current = current.Next;
            }
        }
Пример #6
0
        private void AddToQueueNonPersistent(IndexWorkflowRecord newWorkflow)
        {
            IndexWorkflowRecordNode newWorkflowNode = new IndexWorkflowRecordNode(newWorkflow);

            if (_workflowRecordsTail == null) //if the list is empty
            {
                _workflowRecordsTail            = newWorkflowNode;
                State.State.WorkflowRecordsHead = newWorkflowNode;
            }
            else // otherwise append to the end of the list
            {
                _workflowRecordsTail.Append(newWorkflowNode, ref _workflowRecordsTail);
            }
        }
Пример #7
0
 internal void Clean()
 {
     WorkflowRecord = null;
     Next           = null;
     Prev           = null;
 }
Пример #8
0
 public IndexWorkflowRecordNode(IndexWorkflowRecord workflow)
 {
     WorkflowRecord = workflow;
 }