public Process GetNewProcess(Job job)
 {
     Process proc = null;
     lock (jobIDProcessDictionary)
     {
         proc = new Process();
         jobIDProcessDictionary.Remove(job.jobID);
         jobIDProcessDictionary.Add(job.jobID, proc);
     }
     return proc;
 }
 public JobStatus GetNewJobStatus(Job job)
 {
     JobStatus jobStatus = null;
     lock (jobIDJobStatusDictionary)
     {
         if (jobIDJobStatusDictionary.ContainsKey(job.jobID))
         {
             jobStatus = jobIDJobStatusDictionary[job.jobID];
         }
         else
         {
             jobStatus = new JobStatus();
             jobStatus.jobID = job.jobID;
             jobStatus.trialCount = 0;
             jobStatus.jobProgress = 0;
             jobStatus.jobStatusType = JobStatusType.PROCESSING;
             jobIDJobStatusDictionary.Add(job.jobID, jobStatus);
         }
     }
     return jobStatus;
 }
        private bool ProcessJobWithCache(Job job)
        {
            string cacheKey = job.GetCacheKey();
            string resultString = jobResultCache.GetJobResultStringFromCache(cacheKey);
            if (resultString != null)
            {
                //cache hit
                JobResult jobResult = new JobResult();
                jobResult.job = job;
                jobResult.jobSucceed = true;
                jobResult.resultString = resultString;

                JobStatus jobStatus = GetJobStatusByJobID(job.jobID);
                //mark job status
                if (jobStatus != null)
                {
                    if (jobStatus.jobStatusType != JobStatusType.CANCELED)
                        jobStatus.jobStatusType = JobStatusType.FINISHED;
                }
                else
                {
                    Console.WriteLine(DateTime.Now.ToString("[HH:mm:ss.fff]") + "[Error][OnJobCalcResult] No job status found for jobID=" + job.jobID);
                }
                Client client = clientManager.GetClientByClientKey(jobResult.job.clientKey);
                if (client != null)
                {
                    AsyncServerClientJobCalcResultCastMessage castmsg = new AsyncServerClientJobCalcResultCastMessage();
                    castmsg.jobResult = jobResult;
                    Console.WriteLine("[ProcessJobWithCache] Send job result : " + jobResult.ToString());
                    if (!client.GetAsyncComm().SendCast(castmsg))
                        Console.WriteLine("[Error] SendCast failed!");
                }
                return true;
            }
            return false;
        }
 public void AddFrontWaitingJobQueue(Job job)
 {
     waitingJobQueue.Insert(0, job);
 }
 public JobStatus GetNewJobStatus(Job job)
 {
     JobStatus jobStatus = new JobStatus();
     jobStatus.jobID = job.jobID;
     jobStatus.jobProgress = 0;
     jobStatus.trialCount = 0;
     jobStatus.jobStatusType = JobStatusType.WAITING;
     jobStatusDicByJobID.Add(jobStatus.jobID, jobStatus);
     return jobStatus;
 }
 public Job GetNewJob()
 {
     Job job = new Job();
     job.clientKey = this.clientKey;
     return job;
 }
        public bool StartJobProcessor(Job job)
        {
            Console.WriteLine(DateTime.Now.ToString("[HH:mm:ss.fff]") + string.Format("[{3}][jobID={0,4}] Trying to start worker... {1}/{2}", job.jobID, availableWorkerCount, totalWorkerCount, job.jobClassName));
            if (processorDictionary.ContainsKey(job.processorName))
            {
                lock(workerCountLock)
                {
                    if (availableWorkerCount > 0)
                    {
                        availableWorkerCount--;
                        Task.Factory.StartNew(() =>
                        {
                            processorDictionary[job.processorName].RunJobProcessor(job);


                        });
                        Console.WriteLine(DateTime.Now.ToString("[HH:mm:ss.fff]") + string.Format("[{3}][jobID={0,4}] Job initiated. {1}/{2}", job.jobID, availableWorkerCount, totalWorkerCount, job.jobClassName));
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
            else
            {
                return false;
            }
        }
        public override void RunJobProcessor(Job job)
        {
            int maxRunCount = 2;
            NativeMethods.SetErrorMode(NativeMethods.SetErrorMode(0) |
                               ErrorModes.SEM_NOGPFAULTERRORBOX |
                               ErrorModes.SEM_FAILCRITICALERRORS |
                               ErrorModes.SEM_NOOPENFILEERRORBOX);
            for (int runCount = 1; runCount <= maxRunCount && !jobProcessorManager.IsCanceledJob(job.jobID); runCount++)
            {
                if (runCount > 1)
                {
                    Console.WriteLine(DateTime.Now.ToString("[HH:mm:ss.fff]") + "[Error][JobProcessor] Task start failed. Retry next iteration " + runCount);
                    Thread.Sleep(1000);
                }
                //write file
                string inputFileName = jobProcessorManager.GetNextFilename() + "_" + job.jobID + ".trn";
                string outputFileName = inputFileName + ".res";

                string processorFullPath = Path.Combine(Environment.CurrentDirectory, processorRelativePath);
                string processorWorkingDirectory = Path.GetDirectoryName(processorFullPath);// Path.Combine(Path.GetDirectoryName(processorFullPath), "tmp");
                string IODirectory = Path.Combine(Path.GetDirectoryName(processorFullPath), "tmp");
                if (!Directory.Exists(IODirectory))
                {
                    DirectoryInfo di = Directory.CreateDirectory(IODirectory);
                }
                if (!Directory.Exists(processorWorkingDirectory))
                {
                    DirectoryInfo di = Directory.CreateDirectory(processorWorkingDirectory);
                }
                string inputFileFullPath = Path.Combine(IODirectory, inputFileName);
                string outputFileFullPath = Path.Combine(IODirectory, outputFileName);
                Process proc = null;
                try
                {
                    File.WriteAllText(inputFileFullPath, job.parameter, Encoding.ASCII);
                    File.Delete(outputFileFullPath);
                    string resultStr = null;
                    proc = jobProcessorManager.GetNewProcess(job);
                    
                    if (proc == null)
                    {
                        if (runCount == maxRunCount)
                        {
                            OnJobFailed(job);
                            return;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    proc.StartInfo.FileName = processorFullPath;
                    proc.StartInfo.UseShellExecute = false;
                    proc.StartInfo.RedirectStandardOutput = true;
                    proc.StartInfo.Arguments = "\"" + inputFileFullPath + "\"";
                    proc.StartInfo.WorkingDirectory = processorWorkingDirectory;
                    proc.StartInfo.ErrorDialog = false;
                    
                    if (!proc.Start())
                    {
                        if (runCount == maxRunCount)
                        {
                            OnJobFailed(job);
                            return;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    try
                    {
                        proc.PriorityClass = ProcessPriorityClass.BelowNormal;
                    }
                    catch (Exception)
                    {
                    }
                    bool succeed = false;

                    string line = "";
                    //starting status
                    {
                        JobStatus jobStatus = jobProcessorManager.GetNewJobStatus(job);
                        jobStatus.jobProgress = 0;
                        OnJobProgress(jobStatus, null);
                    }
                    StringBuilder buffer = new StringBuilder();
                    while (true)
                    {
                        bool lineEndFlag = false;
                        string currentBuffer;
                        int outChar = -1;
                        try
                        {
                            outChar = proc.StandardOutput.Read();

                            if (outChar == -1)
                            {
                                //stream closed
                                if (buffer.Length == 0)
                                    //if stream is empty, do nothing
                                    break;
                                else
                                {
                                    //if stream is not empty, process it!
                                    line = buffer.ToString();
                                    lineEndFlag = true;
                                }
                            }
                            else
                            {
                                buffer.Append((char)outChar);
                                currentBuffer = buffer.ToString();
                                if (currentBuffer.EndsWith("\r\n"))
                                {
                                    line = currentBuffer.Substring(0, currentBuffer.Length - 2);
                                    lineEndFlag = true;
                                }
                                else if (currentBuffer.EndsWith("\n"))
                                {
                                    line = currentBuffer.Substring(0, currentBuffer.Length - 1);
                                    lineEndFlag = true;
                                }
                            }
                        }
                        catch (IOException)
                        {
                            if (buffer.Length == 0)
                                //if stream is empty, do nothing
                                break;
                            else
                            {
                                //if stream is not empty, process it!
                                line = buffer.ToString();
                                lineEndFlag = true;
                            }
                        }
                        if (lineEndFlag == true)
                        {
                            line.Trim();
                            buffer.Clear();
                            //pattern : Progress/currentStep/totalStep (Progress/1/10)
                            if (line.StartsWith("Progress/"))
                            {
                                string[] strArr = line.Split('/');
                                if (strArr.Length == 3)
                                {
                                    int curr = int.Parse(strArr[1]);
                                    int total = int.Parse(strArr[2]);

                                    JobStatus jobStatus = jobProcessorManager.GetNewJobStatus(job);
                                    jobStatus.jobProgress = curr / total;
                                    if (OnJobProgress != null)
                                        OnJobProgress(jobStatus, null);
                                }
                            }
                        }
                        if (outChar == -1)
                            break;
                    }

                    //while ((line = proc.StandardOutput.ReadLine()) != null)
                    //{

                    //    //Console.WriteLine(DateTime.Now.ToString("[HH:mm:ss.fff]")+"[Job=" + job.jobID + "] " + line);
                    //    //pattern : Progress/currentStep/totalStep (Progress/1/10)
                    //    if (line.StartsWith("Progress/"))
                    //    {
                    //        string[] strArr = line.Split('/');
                    //        if (strArr.Length == 3)
                    //        {
                    //            int curr = int.Parse(strArr[1]);
                    //            int total = int.Parse(strArr[2]);

                    //            JobStatus jobStatus = jobProcessorManager.GetNewJobStatus(job);
                    //            jobStatus.jobProgress = curr / total;

                    //            OnJobProgress(jobStatus, null);
                    //        }
                    //    }
                    //}

                    proc.WaitForExit();

                    try
                    {
                        resultStr = File.ReadAllText(outputFileFullPath, Encoding.ASCII);
                    }
                    catch (Exception)
                    {
                        if (runCount == maxRunCount)
                        {
                            OnJobFailed(job);
                            return;
                        }
                        else
                        {
                            continue;
                        }
                    }

                    JobResult jobResult = new JobResult();
                    jobResult.job = job;
                    if (resultStr != null)
                    {
                        if (OnJobProgress != null)
                        {
                            JobStatus jobStatus = jobProcessorManager.GetNewJobStatus(job);
                            jobStatus.jobProgress = 1;
                            OnJobProgress(jobStatus, null);
                        }
                        jobResult.jobSucceed = succeed || proc.ExitCode == 0;
                        jobResult.resultString = "OK" + resultStr;
                        if (OnJobCompleted != null)
                        {
                            OnJobCompleted(jobResult, null);
                        }
                        return;
                    }
                    else
                    {
                        if (runCount == maxRunCount)
                        {
                            jobResult.jobSucceed = proc.ExitCode == 0;
                            OnJobCompleted(jobResult, null);
                            return;
                        }
                        else
                        {
                            continue;
                        }
                    }
                }
                catch (Exception e)
                {
                    if (proc != null)
                        proc.Close();
                    Console.WriteLine(DateTime.Now.ToString("[HH:mm:ss.fff]") + "[Error][JobProcessor] Task start failed." + e.ToString());
                    if (runCount == maxRunCount)
                    {
                        OnJobFailed(job);
                        return;
                    }
                    continue;
                }
            }
            if (jobProcessorManager.IsCanceledJob(job.jobID))
                OnJobFailed(job);
            return;
        }
        private void OnJobFailed(Job job)
        {
            JobResult jobResult = new JobResult();
            jobResult.job = job;
            jobResult.jobSucceed = false;
            jobResult.resultString = "OKfail";

            if (OnJobCompleted != null)
                OnJobCompleted(jobResult, null);
        }
 public void WorkerStart(Job job)
 {
     jobDic.Add(job.jobID, job);
     availableWorkerCount--;
 }
 public abstract void RunJobProcessor(Job job);