public WorkItemEventArgs ( WorkItem workItem ) { _workItem = workItem; }
protected static void ReturnToRetrievalQueue ( WorkItem queueWorkItem ) { }
public override WorkItem GetNextWorkItem ( WorkItemSlotCollection slots ) { workItemCandidate = null; #region Process if (ReservePrioritySlot(PriorityScope)) { if (ExecutionState != ProcessExecutionState.Running) { return null; } try { WorkItem workItem = GetWorkItemFromQueue (); if (workItem != null) { Log.Source.TraceData(TraceEventType.Verbose, ProducerMessage.MessageRetrieved, new ContextualLogEntry { Message = "Got a new work item" + workItem, ContextIdentifier = new ContextIdentifier() }); return workItem; } } catch (Exception ex) { // Interrupt should not be a problem CancelPrioritySlotReservation(PriorityScope); Log.Source.TraceData(TraceEventType.Error, ProducerMessage.RetrieveMessageFailed, new ContextualLogEntry { Message = "Error during getting work item." + ex, ContextIdentifier = new ContextIdentifier() }); return null; } CancelPrioritySlotReservation(PriorityScope); } #endregion Process return null; }
public QueueWorkItem ( WorkItem workItem ) : this() { _workItem = workItem; }
/// <summary> /// Returns slot's work item and clears the slot. /// </summary> /// <returns></returns> public WorkItem RetrieveWorkItem() { lock (workItemSyncRoot) { WorkItem retWorkItem = _workItem; _workItem = null; return retWorkItem; } }
public StateQueueWorkItem ( WorkItem workItem, IContextIdentifierHolder messageBody ) : this ( workItem, messageBody, WorkItemProcessStatus.None ) { }
public StateQueueWorkItem ( WorkItem workItem, IContextIdentifierHolder messageBody, WorkItemProcessStatus status ) : base ( workItem //, //null //TODO: **(SD) Extra attention here. I forgot what was the intent ) { _status = status; }
/// <summary> /// Assigns the work item to the slot. /// </summary> /// <exception cref="ArgumentException"> /// When workItem has different priority than the slot it is being assigned to. /// </exception> /// <param name="workItem"></param> public void AssignWorkItem(WorkItem workItem) { if (workItem.SubmissionPriority != SubmissionPriority) { throw new ArgumentException ( "WorkItem with submission type " + workItem.SubmissionPriority + " can't be assigned to the WorkItemSlot with different priority (" + SubmissionPriority + ").", "workItem" ); } lock (workItemSyncRoot) { _workItem = workItem; } }
protected virtual void OnWorkItemRetrieved(WorkItem workItem) { #region Log Log.TraceData(Log.Source,TraceEventType.Verbose, ConsumerMessage.WorkItemRetrieved, new ContextualLogEntry { Message = "Work item retrieved by the " + Name + " comsumer.", ContextIdentifier = workItem.ContextIdentifier }); #endregion Log if (WorkItemRetrieved != null) { WorkItemRetrieved(this, workItem); } }
/// <summary> /// <para>Inserts a <see cref='WorkItem'/> into the <see cref='WorkItemCollection'/> at the specified index.</para> /// </summary> /// <param name='index'>The zero-based index where <paramref name='value'/> should be inserted.</param> /// <param name=' value'>The <see cref='WorkItem'/> to insert.</param> /// <returns><para>None.</para></returns> /// <seealso cref='WorkItemCollection.Add'/> public void Insert(int index, WorkItem value) { List.Insert(index, value); }
/// <summary> /// /// </summary> /// <param name="priority"></param> /// <returns>Retrieved work item or null if not found, didn't pass pre-check, etc.</returns> private WorkItem GetWorkItemFromQueue(SubmissionPriority priority) { //TODO: Pay great attention here, now workItemCandidate is an instance field!!! (SD) workItemCandidate = null; WorkItem workItem = null; TextMessage message = null; Message msgTest = null; #region Get message from queue //var transaction = new CommittableTransaction(); try { #region Get next job from the queue //var //using (DependentTransaction dependentTransaction = // transaction.DependentClone(DependentCloneOption.BlockCommitUntilComplete)) //{ // using (var scope = new TransactionScope(dependentTransaction)) // { //TODO: (SD) Provide timeout option msgTest = queue.ReadNext(); message = msgTest as TextMessage; // scope.Complete(); //} //dependentTransaction.Complete(); if (message == null) { // if token is equal to null then commit here, as // consumer will not get to the item anyway. //if (transaction.TransactionInformation.Status == TransactionStatus.Active) // transaction.Commit(); Log.TraceData(Log.Source, TraceEventType.Verbose, 10001, "Null message received because of the timeout. Queue: " + queue.ServerConfig.Url + ":" + queue.QueueConfig.Name); } else { Log.TraceData(Log.Source, TraceEventType.Verbose, 10002, String.Format("Message [CID:{0}|MID:{1}] received from queue {2}:{3}", message.MessageID, message.CorrelationID, queue.ServerConfig.Url,queue.QueueConfig.Name)); } //} #endregion #region If job is not null create a work item for it if (message != null) { //utf-8 is a default encoding for ems workItemCandidate = new EmsWorkItem(0, 0, WorkItemState.AvailableForProcessing, SubmissionPriority.Normal, Encoding.UTF8.GetBytes(message.Text), false, false, this.Name, new ContextIdentifier { InternalId = 0, ExternalReference = message.CorrelationID, ExternalId = message.MessageID, ContextGuid = Trace.CorrelationManager.ActivityId }, queue, message) { //Transaction = transaction, RetrievedAt = DateTime.Now }; //Trace.CorrelationManager.ActivityId = .ContextUid; Log.TraceData(Log.Source, TraceEventType.Start, 0, String.Format("{0} [{1}:{2}]", message.CorrelationID, queue.ServerConfig.Url, queue.QueueConfig.Name)); // Set transaction on the work item } #endregion this.FailureExceptionHandler.ResetState(); } catch (Exception ex) { // Cleanup will never throw. if (ex is EMSException) queue.Close(); try { queue.Rollback(); // Rollback the commitable transaction //transaction.Rollback(ex); } finally { //transaction.Dispose(); } Log.TraceData(Log.Source, TraceEventType.Error, ProducerMessage.ErrorDuringObtainingTheWorkItem, new ContextualLogEntry { Message = "Exception happened when trying to get item from the message queue (" + queue.ServerConfig.Url + "). " + Environment.NewLine + ex, ContextIdentifier = ((workItemCandidate != null) ? workItemCandidate.ContextIdentifier : new ContextIdentifier()) }); // To review what is the required handling here for us (SD) if (ExecutionState == ProcessExecutionState.Running) { FailureExceptionType type = this.FailureExceptionHandler.HandleFailure(ex); if (type == FailureExceptionType.NonRecoverable) this.Stop(); } else { if (workItemCandidate != null) { Log.TraceData(Log.Source, System.Diagnostics.TraceEventType.Information, ProducerMessage.RetrievedMessageReturnedToTheRetrievalQueue, new ContextualLogEntry { Message = string.Format( "'{0}': Retrieved Recurrence(Id = {1}) Successfully Saved to the {2} queue", Name, workItemCandidate.Id, "" ), ContextIdentifier = workItemCandidate.ContextIdentifier }); return null; } } } #endregion Get message from queue #region Pre-processing checks // Convert queue message to work item // In case sql broker no need to do (SD) if (workItemCandidate != null) { #region WorkItem Diagnostics workItemCandidate.AttachNote("Received from the " + priority + " Queue "); #endregion WorkItem Diagnostics // TODO: //**SD1 - Provide the check for // No checks done now, see the DB driven implementation for the checks samples (SD) // It means as well that we can simply assign item candidate to be our work item workItem = workItemCandidate; // TODO: (SD) Message body will be the xml retrieved from the sql broker workItem.MessageBody = Encoding.UTF8.GetBytes(message.Text); //**message.GetObjectProperty } #endregion Pre-processing checks // Return retrieved work item (or null) return workItem; }
public override WorkItem GetNextWorkItem(WorkItemSlotCollection slots) { //TODO: This will be working on one thread only so skipping the synchronization here Trace.CorrelationManager.ActivityId = Guid.NewGuid(); try { queue.Open(); } catch (Exception ex) { if (!queue.RecoverFromConnectionError(ex)) { Stop(); } return null; } workItemCandidate = null; #region Process if (ReservePrioritySlot(PriorityScope)) { if (ExecutionState != ProcessExecutionState.Running) { return null; } try { WorkItem workItem = GetWorkItemFromQueue(PriorityScope); if (workItem != null) { //Log.TraceData(Log.Source, System.Diagnostics.TraceEventType.Verbose, // ProducerMessage.MessageRetrieved, // new ContextualLogEntry // { // Message = "Got a new work item" + workItem, // ContextIdentifier = new ContextIdentifier() // }); return workItem; } } catch (Exception ex) { // Interrupt should not be a problem CancelPrioritySlotReservation(PriorityScope); Log.TraceData(Log.Source, System.Diagnostics.TraceEventType.Error, ProducerMessage.RetrieveMessageFailed, new ContextualLogEntry { Message = "Error during getting work item." + ex, ContextIdentifier = new ContextIdentifier() }); return null; } CancelPrioritySlotReservation(PriorityScope); } #endregion Process return null; }
/// <summary> /// Assigns work item based onto the candidate. This method has to provide /// chacks if required for the suitability of the candidate item and return /// null item if item is not suitable for processing or construct some other /// work item based on the candidate that would be applicable for processing. /// </summary> /// <param name="candidate">The candidate item to create work item from.</param> /// <returns>null or work item to process</returns> private static WorkItem AssignWorkItemFromCandidate(WorkItem candidate) { //(SD) This direct return should only happen when candidate is suitable // for processing. For this implementation there are no checks return candidate; }
/// <summary> /// Clears the slot. /// </summary> public void Clear() { lock (workItemSyncRoot) { _workItem = null; } }
/// <summary> /// /// </summary> /// <param name="priority"></param> /// <returns>Retrieved work item or null if not found, didn't pass pre-check, etc.</returns> private WorkItem GetWorkItemFromQueue(SubmissionPriority priority) { //TODO: Pay great attention here, now workItemCandidate is an instance field!!! (SD) workItemCandidate = null; WorkItem workItem = null; Tools.Commands.Implementation.IF1.req item = null; Trace.CorrelationManager.ActivityId = Guid.NewGuid(); #region Get message from queue var transaction = new CommittableTransaction(); try { #region Get next job from the queue //var using (DependentTransaction dependentTransaction = transaction.DependentClone(DependentCloneOption.BlockCommitUntilComplete)) { using (var scope = new TransactionScope(dependentTransaction)) { //TODO: (SD) Provide timeout option item = new Tools.Commands.Implementation.IF1.req { reqId = (++IdSequence).ToString(), processingStatus = "P", errorDesc = "ok", returnValue = "ok", updateMechanism = "JMS" }; scope.Complete(); } dependentTransaction.Complete(); if (item == null) { // if token is equal to null then commit here, as // consumer will not get to the item anyway. if (transaction.TransactionInformation.Status == TransactionStatus.Active) transaction.Commit(); } } #endregion #region If job is not null create a work item for it if (item != null) { workItemCandidate = new RequestWorkItem(0, 0, WorkItemState.AvailableForProcessing, SubmissionPriority.Normal, Encoding.UTF8.GetBytes(SerializationUtility.Serialize2String(item)), false, false, this.Name, new ContextIdentifier { InternalId = 0, ExternalReference = IdSequence.ToString(), ExternalId = IdSequence.ToString() }) { Transaction = transaction, RetrievedAt = DateTime.Now }; //**Trace.CorrelationManager.ActivityId = .ContextUid; Log.Source.TraceEvent(TraceEventType.Start, 0, "Received the item " + item); // Set transaction on the work item } #endregion this.FailureExceptionHandler.ResetState(); } catch (Exception ex) { try { // Rollback the commitable transaction transaction.Rollback(ex); } finally { transaction.Dispose(); } Log.TraceData(Log.Source, TraceEventType.Error, ProducerMessage.ErrorDuringObtainingTheWorkItem, new ContextualLogEntry { Message = "Exception happened when trying to get item " + Environment.NewLine + ex, ContextIdentifier = ((workItemCandidate != null) ? workItemCandidate.ContextIdentifier : new ContextIdentifier()) }); // To review what is the required handling here for us (SD) if (ExecutionState == ProcessExecutionState.Running) { FailureExceptionType type = this.FailureExceptionHandler.HandleFailure(ex); if (type == FailureExceptionType.NonRecoverable) this.Stop(); } else { if (workItemCandidate != null) { Log.TraceData(Log.Source, System.Diagnostics.TraceEventType.Information, ProducerMessage.RetrievedMessageReturnedToTheRetrievalQueue, new ContextualLogEntry { Message = string.Format( "'{0}': Retrieved Recurrence(Id = {1}) Successfully Saved to the {2} queue", Name, workItemCandidate.Id, "" ), ContextIdentifier = workItemCandidate.ContextIdentifier }); return null; } } } #endregion Get message from queue #region Pre-processing checks // Convert queue message to work item // In case sql broker no need to do (SD) if (workItemCandidate != null) { #region WorkItem Diagnostics workItemCandidate.AttachNote("Received from the " + priority + " Queue "); #endregion WorkItem Diagnostics // TODO: //**SD1 - Provide the check for // No checks done now, see the DB driven implementation for the checks samples (SD) // It means as well that we can simply assign item candidate to be our work item workItem = workItemCandidate; // TODO: (SD) Message body will be the xml retrieved from the sql broker //**message.GetObjectProperty } #endregion Pre-processing checks // Return retrieved work item (or null) return workItem; }
/// <summary> /// /// </summary> /// <returns>Retrieved work item or null if not found, didn't pass pre-check, etc.</returns> private WorkItem GetWorkItemFromQueue () { //TODO: Pay great attention here, now workItemCandidate is an instance field!!! (SD) workItemCandidate = null; #region Get message from queue var transaction = new CommittableTransaction(); try { Job job; using (DependentTransaction dependentTransaction = transaction.DependentClone(DependentCloneOption.BlockCommitUntilComplete)) { using (var scope = new TransactionScope(dependentTransaction)) { job = ItemProvider.GetNextItem(); scope.Complete(); } dependentTransaction.Complete(); } if (job != null) { PerformanceHandler.HandleEvent("Reads From Queue/sec", 1); workItemCandidate = new RequestWorkItem(job.ContextIdentifier.InternalId, 0, WorkItemState.AvailableForProcessing, SubmissionPriority.Normal, null, false, false, "test", new ContextIdentifier()); // Set transaction on the work item workItemCandidate.Transaction = transaction; workItemCandidate.RetrievedAt = DateTime.Now; workItemCandidate.MessageBody = SerializationUtility.Serialize2ByteArray(job); } else { workItemCandidate = null; } FailureExceptionHandler.ResetState(); } catch (Exception ex) { try { // Rollback the commitable transaction transaction.Rollback(ex); } finally { transaction.Dispose(); } Log.Source.TraceData(TraceEventType.Error, ProducerMessage.ErrorDuringObtainingTheWorkItem, new ContextualLogEntry { Message = "Exception happened when trying to get item from the message queue (" + "queue.QueuePath" + "). " + Environment.NewLine + ex , ContextIdentifier = ((workItemCandidate != null) ? workItemCandidate.ContextIdentifier : new ContextIdentifier()) }); // To review what is the required handling here for us (SD) if (ExecutionState == ProcessExecutionState.Running) { FailureExceptionType type = FailureExceptionHandler.HandleFailure(ex); if (type == FailureExceptionType.NonRecoverable) Stop(); } else { if (workItemCandidate != null) { Log.Source.TraceData(TraceEventType.Information, ProducerMessage.RetrievedMessageReturnedToTheRetrievalQueue, new ContextualLogEntry { Message = string.Format ( "'{0}': Retrieved Recurrence(Id = {1}) Successfully Saved to the {2} queue", Name, workItemCandidate.Id, "" ), ContextIdentifier = workItemCandidate.ContextIdentifier }); return null; } } if (workItemCandidate == null) return null; } #endregion Get message from queue #region Pre-processing checks WorkItem workItem = AssignWorkItemFromCandidate(workItemCandidate); #endregion Pre-processing checks // Return retrieved work item (or null) return workItem; }
/// <summary> /// <para> /// Initializes a new instance of <see cref='Tools.Coordination.Core.WorkItem'/> objects. /// </para> /// </summary> /// <param name='value'> /// A array of <see cref='Tools.Coordination.Core.WorkItem'/> objects with which to intialize the collection /// </param> public WorkItemCollection(WorkItem[] value) { AddRange(value); }
/// <summary> /// <para>Adds a <see cref='WorkItem'/> with the specified value to the /// <see cref='WorkItemCollection'/> .</para> /// </summary> /// <param name='value'>The <see cref='WorkItem'/> to add.</param> /// <returns> /// <para>The index at which the new element was inserted.</para> /// </returns> /// <seealso cref='WorkItemCollection.AddRange'/> public int Add(WorkItem value) { #region WorkItem Diagnostics //if (Tools.Instrumentation.Common.InstrumentationManager.Level==InstrumentationLevel.High) //{ value.AttachNote("Added to the " + Name + " IQ"); //} #endregion WorkItem Diagnostics return List.Add(value); }
/// <summary> /// <para> Removes a specific <see cref='WorkItem'/> from the /// <see cref='WorkItemCollection'/> .</para> /// </summary> /// <param name='value'>The <see cref='WorkItem'/> to remove from the <see cref='WorkItemCollection'/> .</param> /// <returns><para>None.</para></returns> /// <exception cref='System.ArgumentException'><paramref name='value'/> is not found in the Collection. </exception> public void Remove(WorkItem value) { #region WorkItem Diagnostics //if (Tools.Instrumentation.Common.InstrumentationManager.Level==InstrumentationLevel.High) //{ value.AttachNote("Removed from the " + Name + " IQ"); Trace.WriteLine(value.ToString()); //} #endregion WorkItem Diagnostics List.Remove(value); }
/// <summary> /// <para>Copies the elements of an array to the end of the <see cref='WorkItemCollection'/>.</para> /// </summary> /// <param name='value'> /// An array of type <see cref='WorkItem'/> containing the objects to add to the collection. /// </param> /// <returns> /// <para>None.</para> /// </returns> /// <seealso cref='WorkItemCollection.Add'/> public void AddRange(WorkItem[] value) { for (int i = 0; (i < value.Length); i = (i + 1)) { WorkItem nv = GetEntry(value[i].IdHash); if (nv != null) { nv = value[i]; } else { Add(value[i]); } } }
/// <summary> /// <para>Gets a value indicating whether the /// <see cref='WorkItemCollection'/> contains the specified <see cref='WorkItem'/>.</para> /// </summary> /// <param name='value'>The <see cref='WorkItem'/> to locate.</param> /// <returns> /// <para><see langword='true'/> if the <see cref='WorkItem'/> is contained in the collection; /// otherwise, <see langword='false'/>.</para> /// </returns> /// <seealso cref='WorkItemCollection.IndexOf'/> public bool Contains(WorkItem value) { return List.Contains(value); }
/// <summary> /// <para>Returns the index of a <see cref='WorkItem'/> in /// the <see cref='WorkItemCollection'/> .</para> /// </summary> /// <param name='value'>The <see cref='WorkItem'/> to locate.</param> /// <returns> /// <para>The index of the <see cref='WorkItem'/> of <paramref name='value'/> in the /// <see cref='WorkItemCollection'/>, if found; otherwise, -1.</para> /// </returns> /// <seealso cref='WorkItemCollection.Contains'/> public int IndexOf(WorkItem value) { return List.IndexOf(value); }
/// <summary> /// <para>Copies the <see cref='WorkItemCollection'/> values to a one-dimensional <see cref='System.Array'/> instance at the /// specified index.</para> /// </summary> /// <param name='array'><para>The one-dimensional <see cref='System.Array'/> that is the destination of the values copied from <see cref='WorkItemCollection'/> .</para></param> /// <param name='index'>The index in <paramref name='array'/> where copying begins.</param> /// <returns> /// <para>None.</para> /// </returns> /// <exception cref='System.ArgumentException'><para><paramref name='array'/> is multidimensional.</para> <para>-or-</para> <para>The number of elements in the <see cref='WorkItemCollection'/> is greater than the available space between <paramref name='arrayIndex'/> and the end of <paramref name='array'/>.</para></exception> /// <exception cref='System.ArgumentNullException'><paramref name='array'/> is <see langword='null'/>. </exception> /// <exception cref='System.ArgumentOutOfRangeException'><paramref name='arrayIndex'/> is less than <paramref name='array'/>'s lowbound. </exception> /// <seealso cref='System.Array'/> public void CopyTo(WorkItem[] array, int index) { List.CopyTo(array, index); }
public void AddWorkItem(WorkItem workItem) { int startIndex = _indexes[workItem.SubmissionPriority].StartIndex; int endIndex = _indexes[workItem.SubmissionPriority].EndIndex; for (int i = startIndex; i < endIndex; i++) { if (this[i].IsEmpty) { this[i].AssignWorkItem(workItem); #region WorkItem Diagnostics //if (Tools.Instrumentation.Common.InstrumentationManager.Level==InstrumentationLevel.High) //{ workItem.AttachNote("Added to the " + Name + " slot with index " + i); //} #endregion WorkItem Diagnostics _counters[workItem.SubmissionPriority].ItemsPresentCount += 1; return; } } // TODO: Handle the case when there is no space, that // should not happen by design, but anyway ... (SD) throw new ApplicationException ( "There is no space to add work item with priority " + workItem.SubmissionPriority + " . Value of slot collection lookup indeces are: StartInternal=" + startIndex + ", end=" + endIndex ); }
/// <summary> /// <para> Synchronically removes a specific <see cref='WorkItem'/> from the /// <see cref='WorkItemCollection'/> .</para> /// </summary> /// <param name='value'>The <see cref='WorkItem'/> to remove from the <see cref='WorkItemCollection'/> .</param> /// <returns><para>None.</para></returns> /// <exception cref='System.ArgumentException'><paramref name='value'/> is not found in the Collection. </exception> public void SynchronizedRemove(WorkItem value) { lock (this) { List.Remove(value); } }