Exemple #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);
        }
Exemple #2
0
        private List <IndexWorkflowRecord> RemoveFromQueueUntilPunctuation(IndexWorkflowRecordNode from)
        {
            List <IndexWorkflowRecord> workflowRecords = new List <IndexWorkflowRecord>();

            if (from != null && !from.IsPunctuation())
            {
                workflowRecords.Add(from.WorkflowRecord);
            }

            IndexWorkflowRecordNode tmp = from.Next;

            while (tmp != null && !tmp.IsPunctuation())
            {
                workflowRecords.Add(tmp.WorkflowRecord);
                tmp = tmp.Next;
                tmp.Prev.Clean();
            }

            if (tmp == null)
            {
                from.Remove(ref State.State.WorkflowRecordsHead, ref _workflowRecordsTail);
            }
            else
            {
                from.Next = tmp;
                tmp.Prev  = from;
                from.Remove(ref State.State.WorkflowRecordsHead, ref _workflowRecordsTail);
                tmp.Remove(ref State.State.WorkflowRecordsHead, ref _workflowRecordsTail);
            }

            return(workflowRecords);
        }
Exemple #3
0
 private void InitiateWorkerThread()
 {
     if (Interlocked.Exchange(ref _isHandlerWorkerIdle, 0) == 1)
     {
         IndexWorkflowRecordNode punctuatedHead = AddPuctuationAt(BATCH_SIZE);
         Handler.HandleWorkflowsUntilPunctuation(punctuatedHead.AsImmutable()).Ignore();
     }
 }
 private void InitiateWorkerThread()
 {
     if (this.SiloIndexManager.InjectableCode.ShouldRunQueueThread(() => Interlocked.Exchange(ref _isHandlerWorkerIdle, 0) == 1))
     {
         IndexWorkflowRecordNode punctuatedHead = AddPunctuationAt(BATCH_SIZE);
         Handler.HandleWorkflowsUntilPunctuation(punctuatedHead.AsImmutable()).Ignore();
     }
 }
Exemple #5
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;
            }
        }
Exemple #6
0
        public IndexWorkflowRecordNode AppendPunctuation(ref IndexWorkflowRecordNode tail)
        {
            // We never append a punctuation to an existing punctuation; it should never be requested.
            if (IsPunctuation())
            {
                throw new WorkflowIndexException("Adding a punctuation to a work-flow queue that already has a punctuation is not allowed.");
            }

            var punctuation = new IndexWorkflowRecordNode();

            Append(punctuation, ref tail);
            return(punctuation);
        }
Exemple #7
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);
            }
        }
Exemple #8
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;
            }
        }
Exemple #9
0
        public override string ToString()
        {
            int count = 0;
            var res   = new StringBuilder();
            IndexWorkflowRecordNode curr = this;

            do
            {
                ++count;
                res.Append(curr.IsPunctuation() ? "::Punc::" : curr.WorkflowRecord.ToString()).Append(",\n");
                curr = curr.Next;
            } while (curr != null);
            res.Append("Number of elements: ").Append(count);
            return(res.ToString());
        }
Exemple #10
0
        public Task <Immutable <List <IndexWorkflowRecord> > > GetRemainingWorkflowsIn(HashSet <Guid> activeWorkflowsSet)
        {
            var result = new List <IndexWorkflowRecord>();
            IndexWorkflowRecordNode current = State.State.WorkflowRecordsHead;

            while (current != null)
            {
                if (activeWorkflowsSet.Contains(current.WorkflowRecord.WorkflowId))
                {
                    result.Add(current.WorkflowRecord);
                }
                current = current.Next;
            }
            return(Task.FromResult(result.AsImmutable()));
        }
Exemple #11
0
        public void Append(IndexWorkflowRecordNode elem, ref IndexWorkflowRecordNode tail)
        {
            var tmpNext = Next;

            if (tmpNext != null)
            {
                elem.Next    = tmpNext;
                tmpNext.Prev = elem;
            }
            elem.Prev = this;
            Next      = elem;

            if (tail == this)
            {
                tail = elem;
            }
        }
Exemple #12
0
        internal IndexWorkflowQueueBase(Type grainInterfaceType, int queueSequenceNumber, SiloAddress silo, bool isDefinedAsFaultTolerantGrain, GrainId grainId, GrainReference parent)
        {
            State        = new IndexWorkflowQueueState(grainId, silo);
            _iGrainType  = grainInterfaceType;
            _queueSeqNum = queueSequenceNumber;

            _workflowRecordsTail = null;
            _storageProvider     = null;
            __handler            = null;
            _isHandlerWorkerIdle = 1;

            _isDefinedAsFaultTolerantGrain = isDefinedAsFaultTolerantGrain;
            __hasAnyTotalIndex             = 0;

            _writeLock            = new AsyncLock();
            _writeRequestIdGen    = 0;
            _pendingWriteRequests = new HashSet <int>();

            _silo   = silo;
            _parent = parent;
        }
Exemple #13
0
        public void Remove(ref IndexWorkflowRecordNode head, ref IndexWorkflowRecordNode tail)
        {
            if (Prev == null)
            {
                head = Next;
            }
            else
            {
                Prev.Next = Next;
            }

            if (Next == null)
            {
                tail = Prev;
            }
            else
            {
                Next.Prev = Prev;
            }

            Clean();
        }
Exemple #14
0
        internal IndexWorkflowQueueBase(SiloIndexManager siloIndexManager, Type grainInterfaceType, int queueSequenceNumber, SiloAddress silo,
                                        bool isDefinedAsFaultTolerantGrain, Func <GrainReference> parentFunc)
        {
            queueState          = new IndexWorkflowQueueState(silo);
            _grainInterfaceType = grainInterfaceType;
            _queueSeqNum        = queueSequenceNumber;

            _workflowRecordsTail = null;
            __grainStorage       = null;
            __handler            = null;
            _isHandlerWorkerIdle = 1;

            _isDefinedAsFaultTolerantGrain = isDefinedAsFaultTolerantGrain;

            _writeLock            = new AsyncLock();
            _writeRequestIdGen    = 0;
            _pendingWriteRequests = new HashSet <int>();

            _silo            = silo;
            SiloIndexManager = siloIndexManager;
            _lazyParent      = new Lazy <GrainReference>(parentFunc, true);
        }
        internal IndexWorkflowQueueBase(SiloIndexManager siloIndexManager, Type grainInterfaceType, int queueSequenceNumber, SiloAddress silo,
                                        bool isDefinedAsFaultTolerantGrain, Func <GrainReference> parentFunc, GrainReference recoveryGrainReference = null)
        {
            queueState          = new IndexWorkflowQueueState();
            _grainInterfaceType = grainInterfaceType;
            _queueSeqNum        = queueSequenceNumber;
            _grainTypeName      = "Orleans.Indexing.IndexWorkflowQueue-" + IndexUtils.GetFullTypeName(_grainInterfaceType);

            _workflowRecordsTail = null;
            __handler            = null;
            _isHandlerWorkerIdle = 1;

            _isDefinedAsFaultTolerantGrain = isDefinedAsFaultTolerantGrain;
            this._recoveryGrainReference   = recoveryGrainReference;

            _writeLock            = new AsyncLock();
            _writeRequestIdGen    = 0;
            _pendingWriteRequests = new HashSet <int>();

            _silo            = silo;
            SiloIndexManager = siloIndexManager;
            _lazyParent      = new Lazy <GrainReference>(parentFunc, true);
        }
Exemple #16
0
        private async Task <Dictionary <IIndexableGrain, HashSet <Guid> > > GetActiveWorkflowsListsFromGrains(IndexWorkflowRecordNode currentWorkflow)
        {
            var result = new Dictionary <IIndexableGrain, HashSet <Guid> >();
            var grains = new List <IIndexableGrain>();
            var activeWorkflowsSetsTasks = new List <Task <Immutable <HashSet <Guid> > > >();
            var workflowIds = new HashSet <Guid>();

            while (!currentWorkflow.IsPunctuation())
            {
                workflowIds.Add(currentWorkflow.WorkflowRecord.WorkflowId);
                IIndexableGrain g = currentWorkflow.WorkflowRecord.Grain;
                foreach (var updates in currentWorkflow.WorkflowRecord.MemberUpdates)
                {
                    IMemberUpdate updt = updates.Value;
                    if (updt.OperationType != IndexOperationType.None && !result.ContainsKey(g))
                    {
                        result.Add(g, emptyHashset);
                        grains.Add(g);
                        activeWorkflowsSetsTasks.Add(g.AsReference <IIndexableGrain>(_siloIndexManager, _iGrainType).GetActiveWorkflowIdsList());
                    }
                }
                currentWorkflow = currentWorkflow.Next;
            }

            if (activeWorkflowsSetsTasks.Count() > 0)
            {
                Immutable <HashSet <Guid> >[] activeWorkflowsSets = await Task.WhenAll(activeWorkflowsSetsTasks);

                for (int i = 0; i < activeWorkflowsSets.Length; ++i)
                {
                    // Do not include workflowIds that are not in our work queue.
                    result[grains[i]] = new HashSet <Guid>(activeWorkflowsSets[i].Value.Intersect(workflowIds));
                }
            }

            return(result);
        }
Exemple #17
0
 internal void Clean()
 {
     WorkflowRecord = null;
     Next           = null;
     Prev           = null;
 }
 public IndexWorkflowQueueEntry(GrainId queueId, SiloAddress silo)
 {
     WorkflowRecordsHead = null;
     QueueId             = queueId;
     Silo = silo;
 }
Exemple #19
0
        private async Task <Dictionary <IIndexableGrain, HashSet <Guid> > > GetActiveWorkflowsListsFromGrains(IndexWorkflowRecordNode currentWorkflow)
        {
            var result = new Dictionary <IIndexableGrain, HashSet <Guid> >();
            var grains = new List <IIndexableGrain>();
            var activeWorkflowsSetsTasks = new List <Task <Immutable <HashSet <Guid> > > >();

            while (!currentWorkflow.IsPunctuation())
            {
                IIndexableGrain g = currentWorkflow.WorkflowRecord.Grain;
                foreach (var updates in currentWorkflow.WorkflowRecord.MemberUpdates)
                {
                    IMemberUpdate updt = updates.Value;
                    if (updt.GetOperationType() != IndexOperationType.None && !result.ContainsKey(g))
                    {
                        result.Add(g, EMPTY_HASHSET);
                        grains.Add(g);
                        activeWorkflowsSetsTasks.Add(g.AsReference <IIndexableGrain>(InsideRuntimeClient.Current.ConcreteGrainFactory, _iGrainType).GetActiveWorkflowIdsList());
                    }
                }
                currentWorkflow = currentWorkflow.Next;
            }

            if (activeWorkflowsSetsTasks.Count() > 0)
            {
                Immutable <HashSet <Guid> >[] activeWorkflowsSets = await Task.WhenAll(activeWorkflowsSetsTasks);

                for (int i = 0; i < activeWorkflowsSets.Length; ++i)
                {
                    result[grains[i]] = activeWorkflowsSets[i].Value;
                }
            }

            return(result);
        }
Exemple #20
0
        private async Task <Dictionary <IIndexableGrain, HashSet <Guid> > > FtGetActiveWorkflowSetsFromGrains(IndexWorkflowRecordNode currentWorkflow)
        {
            var activeWorkflowSetTasksByGrain = new Dictionary <IIndexableGrain, Task <Immutable <HashSet <Guid> > > >();
            var currentWorkflowIds            = new HashSet <Guid>();

            for (; !currentWorkflow.IsPunctuation; currentWorkflow = currentWorkflow.Next)
            {
                var record = currentWorkflow.WorkflowRecord;
                currentWorkflowIds.Add(record.WorkflowId);
                IIndexableGrain g = record.Grain;
                if (!activeWorkflowSetTasksByGrain.ContainsKey(g) && record.MemberUpdates.Where(ups => ups.Value.OperationType != IndexOperationType.None).Any())
                {
                    activeWorkflowSetTasksByGrain[g] = g.AsReference <IIndexableGrain>(this._siloIndexManager, this._grainInterfaceType).GetActiveWorkflowIdsSet();
                }
            }

            if (activeWorkflowSetTasksByGrain.Count > 0)
            {
                await Task.WhenAll(activeWorkflowSetTasksByGrain.Values);

                // Intersect so we do not include workflowIds that are not in our work queue.
                return(activeWorkflowSetTasksByGrain.ToDictionary(kvp => kvp.Key,
                                                                  kvp => new HashSet <Guid>(kvp.Value.Result.Value.Intersect(currentWorkflowIds))));
            }

            return(new Dictionary <IIndexableGrain, HashSet <Guid> >());
        }
 public IndexWorkflowQueueEntry(SiloAddress silo)
 {
     this.WorkflowRecordsHead = null;
     this.Silo = silo;
 }