/// <summary> /// This method will remove a child job and call any delegate. /// </summary> /// <param name="jobID">The job ID</param> /// <param name="sender">The sender.</param> /// <param name="args">The arguments.</param> /// <returns></returns> protected virtual bool RemoveJob(Guid jobID, object sender, CommandRSEventArgs args) { JobHolder jh; lock (this) { if (!WorkTable.Contains(jobID)) return false; #if (DEBUG) //System.Diagnostics.Debug.WriteLine("Dec: " + jobID.ToString() + " -> " + jobRequests.ToString()); #endif jh = WorkTable[jobID] as JobHolder; if (jh != null) { Interlocked.Decrement(ref jobRequests); //Remove the job. WorkTable.Remove(jh); } } if (jh.RSCallback!=null) jh.RSCallback(sender,args); //Stop any time-out timer. if (jobRequests == 0) ResetTimer(); return true; }
/// <summary> /// This method removes a job from the completion job. /// </summary> /// <param name="oldJobID">The old job to remove.</param> /// <param name="sender">The sender.</param> /// <param name="args">The sender arguments.</param> /// <returns>Returns true if the job was successfully removed.</returns> protected override bool RemoveJob(Guid oldJobID, object sender, CommandRSEventArgs args) { JobHolder oldJob; Guid? nextJobID = null; lock (this) { if (!WorkTable.Contains(oldJobID)) { return false; } oldJob = WorkTable[oldJobID] as JobHolder; } //Execute the call back - this must be done before the job is removed to ensure //that the completion job does not fire too early. try { if (oldJob.RSCallback != null) oldJob.RSCallback(sender, args); } catch (CompletionJobDependencyException) { //This exception will be fired by the parent if the job was not successful. //We should mark the dependency ID as erroneous and any dependent jobs should be cancelled. } catch (Exception ex) { string error = "Completion job error:" + ex.Message; if (JobShouldTrace) { JobTrace("!!" + jobRequests.ToString() + " Job=" + oldJobID.ToString() + " --> " + error); } XimuraAppTrace.WriteLine(error, "Completion Job", EventLogEntryType.Warning); } lock (this) { //Is this a dependency job? If so truncate and pull out the next job. if (oldJob.DependencyID != null && this.mDependencyList.ContainsKey(oldJob.DependencyID)) { //Is there a next job? if (oldJob.NextJob.HasValue) { nextJobID=oldJob.NextJob; JobHolder nextJob = WorkTable[nextJobID.Value] as JobHolder; nextJob.LastJob = oldJob.LastJob; //Yes, so re-adjust the dependency list. mDependencyList[oldJob.DependencyID] = nextJobID.Value; } else //No, so remove the dependency reference. mDependencyList.Remove(oldJob.DependencyID); } Interlocked.Decrement(ref jobRequests); WorkTable.Remove(oldJobID); //This following statement clears the job of any parameters and delegates //and allows Garbage collection to release the resources. if (oldJob!=null) oldJob.Reset(); if (JobShouldTrace) JobTrace("<--" + jobRequests.ToString() + " CJ=" + CompletionJobID.ToString() + " Job=" + oldJobID.ToString()); } //Stop any time-out timer. if (jobRequests == 0) ResetTimer(); if (nextJobID.HasValue) SubmitJob(nextJobID.Value); return true; }
/// <summary> /// This method is used by async callbacks to return the envelope back to the pool. /// </summary> /// <param name="args">The command arguments.</param> private static void EnvelopeReturn(CommandRSEventArgs args) { if (args == null || args.Data == null) return; EnvelopeReturn(args.Data); args.Reset(); }
/// <summary> /// This is the internal callback point for the associated jobs. /// </summary> /// <param name="sender">The sender. This is usually null.</param> /// <param name="args">The job arguments.</param> private void RQCallback(object sender, CommandRSEventArgs args) { Guid jobID = args.ID.Value; JobHolder currentJob = null; Interlocked.Increment(ref jobsReturned); Interlocked.Decrement(ref executingJobs); //If the job exists then remove the job and reset the time out timer. //This method will call the job callback. try { if (RemoveJob(jobID, sender, args)) { if (CheckCompletionJobComplete()) { ThrottleSet(); return; } } } catch (Exception ex) { throw ex; } lock (this) { //Set the throttling status so that jobs will continue. if (mThrottlingQueue == null || mThrottlingQueue.Count == 0) { ThrottleSet(); return; } //Get the next job out of the throttle queue currentJob = mThrottlingQueue.Dequeue(); //Reset the throttling queue if this is the last job. if (throttleThreshold == 0 || mThrottlingQueue.Count < throttleThreshold) ThrottleSet(); } //Process the job from the queue. ParentJob.ProcessRequestAsync(currentJob.ID.Value, currentJob.Data, internalCallback, currentJob.ProgressCallback, currentJob.Priority); Interlocked.Increment(ref jobsSubmitted); }
/// <summary> /// This is the Read call back. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private static void AsyncCDSCallback(object sender, CommandRSEventArgs args) { try { } catch (Exception ex) { throw ex; } finally { EnvelopeReturn(args); } }