コード例 #1
0
        /// <summary>
        /// Query task info
        /// </summary>
        private void QueryTaskInfo()
        {
            TraceHelper.TraceEvent(this.sessionid, TraceEventType.Verbose, "[JobMonitorEntry] Enters QueryTaskInfo method.");
            if (Interlocked.Increment(ref this.registerdPullTask) != 1)
            {
                // register count doesn't change from 0 to 1 means somebody is pulling task, quit
                return;
            }

            bool            shouldExit   = false;
            List <TaskInfo> taskInfoList = null;

            this.pullTaskGap = PullTaskMinGap;

            while (true)
            {
                try
                {
                    TraceHelper.TraceEvent(this.sessionid, TraceEventType.Verbose, "[JobMonitorEntry] Starting get job counters.");
                    ISchedulerJobCounters counters = this.schedulerJob.GetCounters();

                    JobInfo  jobInfo = new JobInfo(this.sessionid, counters);
                    JobState state   = this.schedulerJob.State;

                    TraceHelper.TraceEvent(this.sessionid, TraceEventType.Information, "[JobMonitorEntry] Starting query task info: JobState = {0}\nJobInfo: {1}", state, jobInfo);
                    if (state != this.previousState)
                    {
                        this.previousState = state;
                        if (this.context != null)
                        {
                            // Bug 7144: dispose JobMonitorEntry instance and unsubscribe events if job state changed to Canceled/Finished/Failed
                            shouldExit = (0 == isRequeuingJob) && (state == JobState.Canceled || state == JobState.Finished || state == JobState.Failed);

                            try
                            {
                                // ignore JobState change that happened during job requeue operation.
                                // Note: requeue job takes 3 steps: cancel job, configure job, submit job.  Job state transitions during job requeue, i.e.,
                                // (running) -> cancelling -> cancelled -> configuring -> submitted -> validating ->(queued), will all be ignored.
                                if (0 == this.isRequeuingJob)
                                {
                                    ISchedulerNotify proxy = this.context;
                                    proxy.JobStateChanged(JobStateConverter.FromHpcJobState(state)).ContinueWith(this.OnEndJobStateChanged);
                                    TraceHelper.TraceEvent(this.sessionid, TraceEventType.Information, "[JobMonitorEntry] Job state change event triggered, new state: {0}", state);
                                }
                            }
                            catch (CommunicationException e)
                            {
                                // Channel is aborted, set the context to null
                                TraceHelper.TraceEvent(this.sessionid, TraceEventType.Error, "[JobMonitorEntry] Callback channel is aborted: {0}", e);
                                this.context = null;
                            }
                            catch (Exception e)
                            {
                                TraceHelper.TraceEvent(this.sessionid, TraceEventType.Error, "[JobMonitorEntry] Failed to trigger job state change event: {0}", e);
                            }
                        }
                    }

                    if (this.context != null && (taskInfoList == null || !jobInfo.Equals(this.previousJobInfo)))
                    {
                        try
                        {
                            taskInfoList = this.GetTaskInfo();

                            if (taskInfoList != null)
                            {
                                ISchedulerNotify proxy = this.context;
                                proxy.TaskStateChanged(taskInfoList).ContinueWith(this.OnEndTaskStateChanged, jobInfo);
                                TraceHelper.TraceEvent(this.sessionid, TraceEventType.Information, "[JobMonitorEntry] Task state change event triggered.");
                            }
                        }
                        catch (CommunicationException e)
                        {
                            // Channel is aborted, set the context to null
                            TraceHelper.TraceEvent(this.sessionid, TraceEventType.Error, "[JobMonitorEntry] Callback channel is aborted: {0}", e);
                            this.context = null;
                        }
                        catch (Exception e)
                        {
                            TraceHelper.TraceEvent(this.sessionid, TraceEventType.Error, "[JobMonitorEntry] Failed to trigger task state change event: {0}", e);
                        }
                    }
                }
                catch (Exception e)
                {
                    TraceHelper.TraceEvent(this.sessionid, TraceEventType.Warning, "[JobMonitorEntry] Exception thrown when querying task info: {0}", e);
                }

                // pull task is not registered, quit
                if (Interlocked.Decrement(ref this.registerdPullTask) == 0)
                {
                    break;
                }

                TraceHelper.TraceEvent(this.sessionid, TraceEventType.Information, "[JobMonitorEntry] Waiting {0} miliseconds and start another round of getting task info.", this.pullTaskGap);

                // Sleep and pull task again, clear the register pull task flag
                Thread.Sleep(this.pullTaskGap);
                if (this.pullTaskGap < PullTaskMaxGap)
                {
                    this.pullTaskGap *= 2;
                    if (this.pullTaskGap > PullTaskMaxGap)
                    {
                        this.pullTaskGap = PullTaskMaxGap;
                    }
                }

                this.registerdPullTask = 1;
            }

            if (shouldExit)
            {
                if (this.Exit != null)
                {
                    this.Exit(this, EventArgs.Empty);
                }
            }
        }