/// <summary> /// Launch Master timer method in the controlThread. /// </summary> /// <param name="stepExectuionObject"></param> private void MasterTimerMethod(object stepExectuionObject) { StepExecution stepExecution = (StepExecution)stepExectuionObject; Logger.Debug("-------------------------------------------- Master Timer --------------------------------------------"); string stepName = stepExecution.StepName; ControlQueue masterLifeLineQueue = stepExecution.remoteChunking._masterLifeLineQueue; string masterNoAliveMessage = stepName + dot + bool.FalseString; // stop timer when batch failed if ("FAILED".Equals(stepExecution.ExitStatus.ExitCode)) { masterLifeLineQueue.Send(masterNoAliveMessage); return; } else // continue update workerMap in the stepExecution and check workers alive { Dictionary <string, bool> workerMap = stepExecution.remoteChunking._workerMap; List <string> workerIDList = stepExecution.remoteChunking._workerStartedQueue.GetWorkerIDByMasterName(stepExecution.StepName); foreach (string workerID in workerIDList) { if (!workerMap.ContainsKey(workerID)) { workerMap[workerID] = true; } } ControlQueue workerLifeLineQueue = stepExecution.remoteChunking._workerLifeLineQueue; List <string> workerIDs = new List <string>(workerMap.Keys); workerLifeLineQueue.CheckMessageExistAndConsumeAll(workerIDs, workerMap); } }
/// <summary> /// Launch Worker method in the controlThread. /// </summary> /// <param name="stepExecution"></param> /// <param name="threadWait"></param> public void Worker(StepExecution stepExecution, AutoResetEvent threadWait) { // workerStartedMessage includes stepname and worker id string workerStartedMessage = stepExecution.StepName + dot + stepExecution.remoteChunking.WorkerID.ToString(); // worker send workerStartedMessage in the workerStarted queue for master job to check stepExecution.remoteChunking._workerStartedQueue.Send(workerStartedMessage); int maxMasterWaitWorkerSecond = stepExecution.remoteChunking.MaxMasterWaitWorkerSecond; int _workerTimerseconds = maxMasterWaitWorkerSecond * 1000; // start a timer to let master check worker is still alive or not in every defualt seconds Timer timer = new Timer(WorkerTimerMethod, stepExecution, 0, _workerTimerseconds); bool Isterminate = false; while (!Isterminate) { // send back signal to the afterStep and stop timer when batch failed ControlQueue workerCompletedQueue = stepExecution.remoteChunking._workerCompletedQueue; if ("FAILED".Equals(stepExecution.ExitStatus.ExitCode)) { timer.Dispose(); Isterminate = true; } // when batch completed send back signal to the afterStep and stop timer after send completedmessage to message queue else if ("COMPLETED".Equals(stepExecution.ExitStatus.ExitCode)) { string workerCompletedMessage = stepExecution.JobExecution.JobInstance.JobName + dot + stepExecution.remoteChunking.WorkerID + dot + "COMPLETED"; workerCompletedQueue.Send(workerCompletedMessage); timer.Dispose(); threadWait.Set(); Isterminate = true; } } }
/// <summary> /// Launch Worker timer method in the controlThread. /// </summary> /// <param name="stepExectuionObject"></param> private void WorkerTimerMethod(object stepExectuionObject) { StepExecution stepExecution = (StepExecution)stepExectuionObject; string workerIdMessage = stepExecution.StepName + dot + stepExecution.remoteChunking.WorkerID.ToString(); Logger.Info("-------------------------------------------- Worker Timer --------------------------------------------"); ControlQueue workerLifeLineQueue = stepExecution.remoteChunking._workerLifeLineQueue; string workerAliveMessage = workerIdMessage + dot + bool.TrueString + dot + DateTime.Now.ToString(); string workerNoAliveMessage = workerIdMessage + dot + bool.FalseString + dot + DateTime.Now.ToString(); // stop timer when batch failed if ("FAILED".Equals(stepExecution.ExitStatus.ExitCode)) { workerLifeLineQueue.Send(workerNoAliveMessage); Logger.Debug(workerIdMessage + "-----------NoAlive------------------"); return; } else // continue send workerAliveMessage to the workerLifeLineQueue { Logger.Debug(workerIdMessage + "-----------Alive------------------"); workerLifeLineQueue.Send(workerAliveMessage); } }
public static JobExecution WorkerStart(string xmlJobFile, UnityLoader loader, string hostName, string username = "******", string password = "******", int workerUpdateTimeInterval = 15) { ControlQueue _controlQueue = GetControlQueue(controlQueueName, hostName, username, password); int messageCount = _controlQueue.GetMessageCount(); XmlJob job = null; TimeSpan WorkerUpdatetimeInterval = TimeSpan.FromSeconds(workerUpdateTimeInterval); if (messageCount != 0) { for (int i = 0; i < messageCount; i++) { string fileName = Path.GetFileName(xmlJobFile); string message = _controlQueue.Receive(fileName); if (ValidateMessage(message)) // for 3 items { Tuple <XmlJob, string, int, bool> tuple = ValidateFileName(message, xmlJobFile); if (tuple.Item4) { // Resend the message to the controlQueue if (tuple.Item3 > 0) { _controlQueue.Send(tuple.Item2); } job = tuple.Item1; Guid guid = Guid.NewGuid(); foreach (XmlStep step in job.JobElements) { step.RemoteChunking = new XmlRemoteChunking(); step.RemoteChunking.HostName = hostName; step.RemoteChunking.Master = false; step.RemoteChunking.WorkerID = guid.ToString(); } break; } } } } else { do { messageCount = _controlQueue.GetMessageCount(); if (messageCount != 0) { for (int i = 0; i < messageCount; i++) { string fileName = Path.GetFileName(xmlJobFile); string message = _controlQueue.Receive(fileName); if (ValidateMessage(message)) // for 3 items { Tuple <XmlJob, string, int, bool> tuple = ValidateFileName(message, xmlJobFile); if (tuple.Item4) { // Resend the message to the controlQueue if (tuple.Item3 > 0) { _controlQueue.Send(tuple.Item2); } job = tuple.Item1; Guid guid = Guid.NewGuid(); foreach (XmlStep step in job.JobElements) { step.RemoteChunking = new XmlRemoteChunking(); step.RemoteChunking.HostName = hostName; step.RemoteChunking.Master = false; step.RemoteChunking.WorkerID = guid.ToString(); } break; } } } break; } else { Logger.Info("No master job provided. Wait for worker {0} seconds.", WorkerUpdatetimeInterval.TotalSeconds); Thread.Sleep(WorkerUpdatetimeInterval); //throw new JobExecutionException("No master job provided"); } } while (messageCount == 0); } _controlQueue.Requeue(); loader.Job = job; var jobOperator = (SimpleJobOperator)BatchRuntime.GetJobOperator(loader); var executionId = jobOperator.StartNextInstance(job.Id); return(jobOperator.JobExplorer.GetJobExecution((long)executionId)); }
/// <summary> /// Launch Master method in the controlThread. /// </summary> /// <param name="stepExecution"></param> /// <param name="threadWait"></param> public void Master(StepExecution stepExecution, AutoResetEvent threadWait) { // clean up all message queues stepExecution.remoteChunking.CleanAllQueue(); // get workerxml name string WorkerXml = stepExecution.remoteChunking.WorkerFileName; // get worker max numbers int workerMaxNumber = stepExecution.remoteChunking.WorkerMaxNumber; // configuration information includes stepname , workerxml name, and worker max numbers string message = stepExecution.StepName + semicolon + WorkerXml + semicolon + workerMaxNumber.ToString(); // master send configuration information in the control queue for worker job to execute stepExecution.remoteChunking._controlQueue.Send(message); int maxMasterWaitWorkerSecond = stepExecution.remoteChunking.MaxMasterWaitWorkerSecond; int maxMasterWaitWorkerRetry = stepExecution.remoteChunking.MaxMasterWaitWorkerRetry; TimeSpan _MasterWaitWorkerTimeout = TimeSpan.FromSeconds(maxMasterWaitWorkerSecond); // check at least one worker started if (WaitForAtLeastWorkerStarted(stepExecution, maxMasterWaitWorkerRetry, _MasterWaitWorkerTimeout)) { // send back signal to the beforeStep threadWait.Set(); bool Isterminate = false; int _masterTimerseconds = maxMasterWaitWorkerSecond * 1000; // start a timer to check worker is still alive or not in every defualt seconds Timer timer = new Timer(MasterTimerMethod, stepExecution, 0, _masterTimerseconds); while (!Isterminate) { ControlQueue masterQueue = stepExecution.remoteChunking._masterQueue; // send back signal to the afterStep and stop timer when batch failed if ("FAILED".Equals(stepExecution.ExitStatus.ExitCode)) { Isterminate = true; timer.Dispose(); threadWait.Set(); } // when batch completed send back signal to the afterStep and stop timer after send completedmessage to message queue and check all workers completed else if ("COMPLETED".Equals(stepExecution.ExitStatus.ExitCode)) { string masterCompletedMessage = "master" + dot + stepExecution.StepName + dot + stepExecution.ExitStatus.ExitCode; int maxWorkerCompleteMessageNeeded = workerMaxNumber; while (maxWorkerCompleteMessageNeeded > 0) { masterQueue.Send(masterCompletedMessage); maxWorkerCompleteMessageNeeded--; } List <string> failList = WaitForWorkerCompleted(stepExecution, workerMaxNumber, maxMasterWaitWorkerSecond, _MasterWaitWorkerTimeout); timer.Dispose(); if (failList.Count > 0) { stepExecution.ExitStatus = ExitStatus.Failed; } threadWait.Set(); Isterminate = true; } } } }