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); }
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); }
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(); } }
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; } }
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); }
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); } }
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; } }
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()); }
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())); }
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; } }
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; }
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(); }
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); }
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); }
internal void Clean() { WorkflowRecord = null; Next = null; Prev = null; }
public IndexWorkflowQueueEntry(GrainId queueId, SiloAddress silo) { WorkflowRecordsHead = null; QueueId = queueId; Silo = silo; }
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); }
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; }