public bool StopJob(string jobName) { lock (JobLock) { return(ActiveJobs.Remove(jobName)); } }
public override void HaltJob(IOperationModel operationModel) { foreach (var executionId in ActiveJobs[operationModel].Keys) { ActiveJobs[operationModel][executionId].Stop(); ActiveJobs[operationModel][executionId].JobUpdate -= job_JobUpdate; ActiveJobs[operationModel][executionId].JobCompleted -= job_JobCompleted; } ActiveJobs.Remove(operationModel); }
public void Shutdown() { lock (JobLock) { State = DispatcherState.Terminated; JobList.Clear(); ActiveJobs.Clear(); Monitor.Pulse(JobLock); } }
protected void JobManagerThread() { while (State != DispatcherState.Terminated) { bool isEarlyWakening = true; Monitor.Enter(JobLock); if (JobList.Count == 0) { Monitor.Wait(JobLock); } else { int waitTime = JobList.Min.GetCycle(); if (waitTime > 0) { isEarlyWakening = Monitor.Wait(JobLock, waitTime); } else { isEarlyWakening = false; } } if (!isEarlyWakening && State != DispatcherState.Terminated) { JobTask task = JobList.Min; // Get job with lowest expiration value if (!ActiveJobs.Contains(task.JobName)) // Is job still active { JobList.Remove(task); Monitor.Exit(JobLock); continue; } Monitor.Exit(JobLock); task.CalculateNextInvocation(); DispatcherManager.GameDispatcher.AddTask(task, true); } else { Monitor.Exit(JobLock); } } }
private void StopCompletedJobs() { for (int i = 0; i < ActiveJobs.Count; i++) { var job = ActiveJobs[i]; if (job.GetCompletionPercentage() >= 1.0f) { Money += job.Job.Job.OfferedReward; var finalDestination = job.Job.Job.To; var finalPlace = WorldState.GetStateForPlace(job.Job.Job.To); job.Job.Job.JobWasCompletedSuccesfully(); // Stay at location if owned + setting to stay there is enabled, or if it is the original location. // else return to original location. if (WorldState.PlaceOwned(finalDestination) && (job.Assignment.StayAtLocation || job.Employee.OriginalLocation == finalDestination)) { ActiveJobs.RemoveAt(i); i--; // Employee is now in the employee list of the destination place. job.Employee.CurrentJob = null; finalPlace.AddEmployee(job.Employee); continue; } else { ActiveJobs.RemoveAt(i); i--; // If the final stop place is not owned, make driver go back to original location. var scheduledJob = new ScheduledJob(job.Job.Job.Reverse(), job.Job.ShipTimes); ActiveJob returnJob = new ActiveJob(scheduledJob, job.Assignment, GetNextLeavingTimeslot(), job.Employee); job.Employee.CurrentJob = returnJob; ActiveJobs.Add(returnJob); finalPlace.EmployeeStateChanged(); continue; } } } }
public void AddJob(string jobName, JobTask job) { lock (JobLock) { bool needSignal = false; if (State == DispatcherState.Running) { needSignal = JobList.Count == 0; job.JobName = jobName; ActiveJobs.Add(jobName); JobList.Add(job); } if (needSignal) { Monitor.Pulse(JobLock); } } }
private void StartJob(PlaceState place, ShipTimeAssignment assignee, ScheduledJob job) { if (!place.Employees.Contains(assignee.AssignedEmployee)) { job.Job.JobWasCompletedUnsuccesfully(); MessageLog.AddError(string.Format("{0} {1} missed their trip to {2} from {3} at {4}", assignee.AssignedEmployee.Name, assignee.AssignedEmployee.Id, job.Job.To.Name, job.Job.From.Name, assignee.Time.ToString("h':'m''"))); return; } var employee = assignee.AssignedEmployee; if (employee.AssignedTruck == null) { MessageLog.AddError(string.Format("{0} {1} does not have a truck to drive to {2} from {3} at {4}", assignee.AssignedEmployee.Name, assignee.AssignedEmployee.Id, job.Job.To.Name, job.Job.From.Name, assignee.Time.ToString("h':'m''"))); return; } if (employee.CurrentJob == null) { employee.CurrentLocation = null; place.Employees.Remove(assignee.AssignedEmployee); var activeJob = new ActiveJob(job, assignee, Time - TimeSpan.FromMinutes(Time.Minute % 15), employee); Money -= activeJob.GasPrice(); employee.CurrentJob = activeJob; ActiveJobs.Add(activeJob); MessageLog.AddInfo(string.Format("{0} left {1}, driving to {2}", assignee.AssignedEmployee.Name, job.Job.From.Name, job.Job.To.Name)); } }
/** * Takes messages off the internal message queue and handles them by either * sending responses, forwarding the message on, or processing it internally */ private void ProcessMessagesThreadProc() { // A response message queue used to send messages back to the one which sent it Queue <AgentMessage> ResponseMessageQueue = new Queue <AgentMessage>(); while (AgentHasShutDown == false) { StartTiming("ProcessMessage-Internal", true); lock ( MessageQueueLock ) { // Swap the SM and PM message queue to keep things moving at full speed Queue <AgentMessage> Temp = MessageQueuePM; MessageQueuePM = MessageQueueSM; MessageQueueSM = Temp; } // Process all messages currently in the queue while (MessageQueuePM.Count > 0) { Debug.Assert(ResponseMessageQueue.Count == 0); // Get and process the next message AgentMessage NextMessage = MessageQueuePM.Dequeue(); Debug.Assert(NextMessage != null); bool bMessageHandled = false; switch (NextMessage.Type) { case EMessageType.SIGNAL: { if (NextMessage is DisconnectionSignalMessage) { // Mark the connection as inactive DisconnectionSignalMessage DisconnectMessage = NextMessage as DisconnectionSignalMessage; Log(EVerbosityLevel.Informative,ELogColour.Green,String.Format("[CloseConnection] Connection disconnected {0:X8}",DisconnectMessage.ConnectionToDisconnect.Handle)); DisconnectMessage.ConnectionToDisconnect.CurrentState = ConnectionState.DISCONNECTED; DisconnectMessage.ConnectionToDisconnect.DisconnectedTime = DateTime.UtcNow; } // Signal the message and move on AgentSignalMessage SignalMessage = NextMessage as AgentSignalMessage; SignalMessage.ResetEvent.Set(); bMessageHandled = true; } break; case EMessageType.TIMING: { Connection FromConnection; if ((Connections.TryGetValue(NextMessage.From,out FromConnection))) { Connection ToConnection; if ((Connections.TryGetValue(NextMessage.To,out ToConnection)) && (ToConnection is LocalConnection)) { // Handle message AgentTimingMessage TimingMessage = NextMessage as AgentTimingMessage; AgentApplication.UpdateMachineState(MachineNameFromConnection(FromConnection),TimingMessage.ThreadNum,TimingMessage.State); bMessageHandled = true; } } } break; case EMessageType.TASK_REQUEST: { // Look up the requesting connection Debug.Assert(NextMessage.From != Constants.INVALID); Connection RequestingConnection; if (Connections.TryGetValue(NextMessage.From,out RequestingConnection)) { // Look up the specified Job AgentJob JobToAskForTasks = RequestingConnection.Job; if (JobToAskForTasks != null) { // If we get a valid response back, add it to the queue AgentTaskRequestResponse Response = JobToAskForTasks.GetNextTask(RequestingConnection); if (Response != null) { ResponseMessageQueue.Enqueue(Response); // Specifications and releases are always handled here, but // reservations are special in that we will send a reservation // back to local connections but we'll need to make sure the // message continues on to remote connections. if ((Response.ResponseType == ETaskRequestResponseType.SPECIFICATION) || (Response.ResponseType == ETaskRequestResponseType.RELEASE) || ((Response.ResponseType == ETaskRequestResponseType.RESERVATION) && (JobToAskForTasks.Owner is LocalConnection))) { bMessageHandled = true; } } } else { // Unable to find the Job, just send back a release message Log(EVerbosityLevel.Verbose,ELogColour.Orange,"[ProcessMessage] Unable to find Job for Task Request; may have been closed"); //ResponseMessageQueue.Enqueue( new AgentTaskRequestResponse( RequestingConnection.Job.JobGuid, // ETaskRequestResponseType.RELEASE ) ); bMessageHandled = true; } } else { // Unable to find the connection, swallow the request Log(EVerbosityLevel.Verbose,ELogColour.Orange,"[ProcessMessage] Unable to find owning Connection for Task Request"); bMessageHandled = true; } } break; case EMessageType.TASK_STATE: { // Look up the sending connection Debug.Assert(NextMessage.From != Constants.INVALID); Connection SendingConnection; if ((Connections.TryGetValue(NextMessage.From,out SendingConnection)) && (SendingConnection.Job != null)) { // Look up the specified Job AgentJob UpdatedJob; if (ActiveJobs.TryGetValue(SendingConnection.Job.JobGuid,out UpdatedJob)) { AgentTaskState UpdatedTaskState = NextMessage as AgentTaskState; UpdatedJob.UpdateTaskState(UpdatedTaskState); if (UpdatedJob.Owner is LocalConnection) { // If the Task state change is of a type potentially interesting to // the Instigator, return it switch (UpdatedTaskState.TaskState) { case EJobTaskState.TASK_STATE_INVALID: case EJobTaskState.TASK_STATE_COMPLETE_SUCCESS: case EJobTaskState.TASK_STATE_COMPLETE_FAILURE: // For these message types, allow the message to continue on break; default: // Nothing to do otherwise, mark the message as handled bMessageHandled = true; break; } } else { // Always send messages on for remote connections } } else { // Unable to find the Job, swallow the request Log(EVerbosityLevel.Verbose,ELogColour.Orange,"[ProcessMessage] Unable to find Job for Task Request"); bMessageHandled = true; } } else { // Unable to find the connection, swallow the request Log(EVerbosityLevel.Verbose,ELogColour.Orange,"[ProcessMessage] Unable to find owning Connection for Task Request"); bMessageHandled = true; } } break; } // If the message was not handled completely, send it on if (bMessageHandled == false) { // Look up who the message is being sent to and make sure they're // still active and if not, ignore the message Connection Recipient; Debug.Assert(NextMessage.To != Constants.INVALID); if (Connections.TryGetValue(NextMessage.To,out Recipient)) { if (Recipient is LocalConnection) { // If the recipient is local, place it in the proper queue // and signal that a message is ready LocalConnection LocalRecipient = Recipient as LocalConnection; lock (LocalRecipient.MessageQueue) { LocalRecipient.MessageQueue.Enqueue(NextMessage); string NewLogMessage = String.Format("Step 2 of 4 for message: ({0:X8} -> {1:X8}), {2}, Message Count {3} (Local Connection)", NextMessage.To, NextMessage.From, NextMessage.Type, LocalRecipient.MessageQueue.Count); Log(EVerbosityLevel.SuperVerbose,ELogColour.Green,NewLogMessage); LocalRecipient.MessageAvailableSignal(); } } else { Debug.Assert(Recipient is RemoteConnection); // If the recipient is remote, send the message via SendMessage // unless the message is a Task being sent back, which is sent // via the dedicated Task API RemoteConnection RemoteRecipient = Recipient as RemoteConnection; if (NextMessage is AgentTaskSpecification) { // All new Tasks are sent via the dedicated Task API AgentTaskSpecification TaskSpecification = NextMessage as AgentTaskSpecification; Hashtable RemoteInParameters = new Hashtable(); RemoteInParameters["Version"] = ESwarmVersionValue.VER_1_0; RemoteInParameters["Specification"] = TaskSpecification; Hashtable RemoteOutParameters = null; Int32 Error = RemoteRecipient.Interface.AddTask(RemoteRecipient.Handle,RemoteInParameters,ref RemoteOutParameters); if (Error >= 0) { // Perhaps we should be sending an accept message back? } else { AgentTaskState UpdateMessage; if (Error == Constants.ERROR_CONNECTION_DISCONNECTED) { // Special case of the connection dropping while we're adding the // task, say it's been killed to requeue UpdateMessage = new AgentTaskState(TaskSpecification.JobGuid, TaskSpecification.TaskGuid, EJobTaskState.TASK_STATE_KILLED); } else { // All other error cases will be rejections UpdateMessage = new AgentTaskState(TaskSpecification.JobGuid, TaskSpecification.TaskGuid, EJobTaskState.TASK_STATE_REJECTED); } AgentJob Job; if (ActiveJobs.TryGetValue(TaskSpecification.JobGuid,out Job)) { Job.UpdateTaskState(UpdateMessage); } } } else { // All standard messages are sent via the SendMessage API Hashtable RemoteInParameters = new Hashtable(); RemoteInParameters["Version"] = ESwarmVersionValue.VER_1_0; RemoteInParameters["Message"] = NextMessage; Hashtable RemoteOutParameters = null; RemoteRecipient.Interface.SendMessage(NextMessage.To,RemoteInParameters,ref RemoteOutParameters); } string NewLogMessage = String.Format("Step 2 of 2 for message: ({0:X8} -> {1:X8}), {2}, (Remote Connection)", NextMessage.To, NextMessage.From, NextMessage.Type); Log(EVerbosityLevel.SuperVerbose,ELogColour.Green,NewLogMessage); } } else { Log(EVerbosityLevel.Informative,ELogColour.Orange,"ProcessMessage: Message sent to invalid connection, ignoring: " + NextMessage.Type.ToString()); } } // If there are any responses to the message, send them if (ResponseMessageQueue.Count > 0) { foreach (AgentMessage NextResponse in ResponseMessageQueue) { // For each one of the messages, set the routing fields properly NextResponse.To = NextMessage.From; NextResponse.From = NextMessage.To; // And then queue the message back up immediately MessageQueuePM.Enqueue(NextResponse); } ResponseMessageQueue.Clear(); } } StopTiming(); // Wait for a message to become available and once unlocked, swap the queues // and check for messages to process. Set a timeout, so we'll wake up every // now and then to check for a quit signal at least MessageQueueReady.WaitOne(500); } }
private void cbxActiveJobs_SelectedIndexChanged(object sender, EventArgs e) { _activeJobs = (ActiveJobs)Enum.Parse(typeof(ActiveJobs), this.cbxActiveJobs.SelectedItem.ToString()); }
public IDEAQueryExecuter() { var stream = Observable.FromEventPattern <ExecuteOperationModelEventArgs>(this, "ExecuteQueryEvent"); stream.GroupByUntil(k => k.EventArgs.OperationModel, g => Observable.Timer(TimeSpan.FromMilliseconds(50))) .SelectMany(y => y.FirstAsync()) .Subscribe(async arg => { var dispatcher = CoreApplication.MainView.CoreWindow.Dispatcher; await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { var operationModel = arg.EventArgs.OperationModel; operationModel.ResultCauserClone = operationModel.Clone(); operationModel.Result = null; if (ActiveJobs.ContainsKey(operationModel) && arg.EventArgs.StopPreviousExecution) { foreach (var executionId in ActiveJobs[operationModel].Keys) { ActiveJobs[operationModel][executionId].Stop(); ActiveJobs[operationModel][executionId].JobUpdate -= job_JobUpdate; ActiveJobs[operationModel][executionId].JobCompleted -= job_JobCompleted; } ActiveJobs.Remove(operationModel); } // determine if new job is even needed (i.e., are all relevant inputfieldmodels set) OperationJob newJob = null; if (operationModel is HistogramOperationModel) { var histogramOperationModel = (HistogramOperationModel)operationModel; if (((histogramOperationModel.VisualizationType == VisualizationType.table) && (histogramOperationModel.AttributeTransformationModels.Count > 0)) || ((histogramOperationModel.VisualizationType != VisualizationType.table) && histogramOperationModel.GetAttributeUsageTransformationModel(AttributeUsage.X).Any() && histogramOperationModel.GetAttributeUsageTransformationModel(AttributeUsage.Y).Any())) { newJob = new HistogramOperationJob( histogramOperationModel, TimeSpan.FromMilliseconds(MainViewController.Instance.MainModel.ThrottleInMillis), (int)MainViewController.Instance.MainModel.SampleSize); } } else if (operationModel is StatisticalComparisonOperationModel) { var statisticalComparisonOperationModel = (StatisticalComparisonOperationModel)operationModel; newJob = new StatisticalComparisonOperationJob( statisticalComparisonOperationModel, TimeSpan.FromMilliseconds(MainViewController.Instance.MainModel.ThrottleInMillis), (int)MainViewController.Instance.MainModel.SampleSize); } else if (operationModel is ExampleOperationModel) { var exampleOperationModel = (ExampleOperationModel)operationModel; newJob = new ExampleOperationJob( exampleOperationModel, TimeSpan.FromMilliseconds(MainViewController.Instance.MainModel.ThrottleInMillis), (int)MainViewController.Instance.MainModel.SampleSize); } else if (operationModel is RiskOperationModel) { var riskOperationModel = (RiskOperationModel)operationModel; newJob = new RiskOperationJob( riskOperationModel, TimeSpan.FromMilliseconds(MainViewController.Instance.MainModel.ThrottleInMillis)); } else if (operationModel is StatisticalComparisonDecisionOperationModel) { var riskOperationModel = (StatisticalComparisonDecisionOperationModel)operationModel; newJob = new StatisticalComparisonDecisionOperationJob( riskOperationModel, TimeSpan.FromMilliseconds(MainViewController.Instance.MainModel.ThrottleInMillis)); } if (newJob != null) { if (!ActiveJobs.ContainsKey(operationModel)) { ActiveJobs.Add(operationModel, new Dictionary <int, OperationJob>()); } ActiveJobs[operationModel][operationModel.ExecutionId] = newJob; newJob.JobUpdate += job_JobUpdate; newJob.JobCompleted += job_JobCompleted; newJob.Start(); } }); }); }