void Start() { foreach (var i in incidentsToProcess.GetConsumingEnumerable()) { var allocations = incidentRepository.GetOpenAllocation(i.IncidentId).ToList(); if (allocations.Count() == 0) { // could not find the allocation... continue; } Allocation allocation = allocations.First(); if (allocations.Count() > 1) { logger.Info("Oops, multiple allocations found. Pick one, cancel the others."); foreach (var a in allocations.Skip(1)) { allocationRepository.CancelAllocation(a.AllocationId, false); } } var ambulance = ambulanceRepository.Get(allocation.AmbulanceId); try { if (DateTime.Now - allocation.AllocationTimestamp > TimeSpan.FromSeconds(5 * 60 / 10)) { logger.Info("Cancel allocation '{0}'", allocation.AllocationId); //ambulanceRepository.UpdateStatus(allocation.AmbulanceId, // AmbulanceStatus.Unavailable); allocationRepository.CancelAllocation(allocation.AllocationId, false); } else { logger.Info("Mobilize ambulance {0} for incident {1}", allocation.AmbulanceId, allocation.IncidentId); var m = new MobilizationMessage(allocation.AmbulanceId, allocation.AllocationId, i.Latitude, i.Longitude, allocation.HospitalId); // Send mobilization order to MDT sender.Send(m, ambulance.Port); // Send fax to home station // Make radio or phone call OnMobilizationSent(allocation); } } catch (Exception e) { logger.Error("Error during mobilization: {0}", e.Message); logger.Error(e.StackTrace); logger.Info("Cancel allocation '{0}'", allocation.AllocationId); allocationRepository.CancelAllocation(allocation.AllocationId, true); } } }
public void Display(MobilizationMessage m) { logger.Info("Display message: " + m); Messages.Push(m); if (Mobilized != null) { Mobilized(this, EventArgs.Empty); } }
void OnMobilized(object sender, EventArgs e) { var lastMessage = (MobilizationMessage)mdt.Messages.Pop(); if (mobilized) { if (lastMessage.AllocationId != lastMob.AllocationId) { logger.Info("Ambulance {0} is already mobilized on mobilization {1}. Refuse mobilization.", this.mdt.ambulanceId, lastMob.AllocationId); mdt.RefuseMobilization(lastMessage.AllocationId); } return; // throw new NotImplementedException("Ambulance already mobilized"); } var refuseMobilization = SimulatedEnvironment.RefuseMobilization(this); if (refuseMobilization) { logger.Info("Refuse mobilization."); mdt.RefuseMobilization(lastMessage.AllocationId); return; } mdt.AcceptMobilization(lastMessage.AllocationId); // Cancel all current tasks, we got something to do! foreach (var tt in cancelSources) { tt.Cancel(); } cancelSources.Clear(); // Stop the ambulance currentRoute = new ConcurrentQueue <Coordinate> (); // Wait for completion of all the pending stuff! logger.Info("Wait for all tasks to complete."); try { Task.WaitAll(tasks.ToArray()); } catch (AggregateException ee) { foreach (var v in ee.InnerExceptions) { Console.WriteLine(ee.Message + " " + v.Message); } } logger.Info("All tasks completed."); tasks.Clear(); var cancelSource = new CancellationTokenSource(); cancelSources.Add(cancelSource); var cancelToken = cancelSource.Token; var action = new Action(() => { mobilized = true; lastMob = lastMessage; logger.Info("Ambulance {0} mobilized on {1}", mdt.ambulanceId, lastMessage.AllocationId); // Compute route var route = mapService.Calculate(mdt.latitude, mdt.longitude, lastMessage.IncidentLatitude, lastMessage.IncidentLongitude); //var coin = r.Next(0, 10); //if (coin >= 5) { // logger.Info("Refuse mobilization"); // mobilized = false; // mdt.RefuseMobilization(lastMessage.AllocationId); // return; //} else { // logger.Info("Accept mobilization"); //} logger.Info("About to confirm leaving"); Thread.Sleep(TimeSpan.FromSeconds(120 / 10)); if (SimulatedEnvironment.PressLeavingButton(this)) { mdt.SetLeaving(); } if (cancelToken.IsCancellationRequested == true) { Console.WriteLine("Task was cancelled."); cancelToken.ThrowIfCancellationRequested(); } homeStation.AmbulanceAtStation.Remove(this); // Move to incident logger.Info("Ambulance {0} to incident", mdt.ambulanceId); SimulateMove(route, cancelToken); if (cancelToken.IsCancellationRequested == true) { Console.WriteLine("Task was cancelled."); cancelToken.ThrowIfCancellationRequested(); } bool onScenePressed = false; if (SimulatedEnvironment.PressOnSceneButton(this)) { mdt.SetOnScene(); onScenePressed = true; } // Resolve incident logger.Info("Ambulance {0} on scene", mdt.ambulanceId); var timeToWait = 15; // r.Next(15, 30); logger.Info("Ambulance {0} work {1}m on scene", mdt.ambulanceId, timeToWait); for (int i = 0; i < timeToWait; i++) { //if (!onScenePressed && SimulatedEnvironment.PressOnSceneButton(this)) { // mdt.SetOnScene(); // onScenePressed = true; //} Thread.Sleep(1000); } if (cancelToken.IsCancellationRequested == true) { Console.WriteLine("Task was cancelled."); cancelToken.ThrowIfCancellationRequested(); } // Move to hospital logger.Info("Ambulance {0} to hospital {1}", mdt.ambulanceId, lastMessage.HospitalIdentifier); var hospitalCoordinates = hospitals[lastMessage.HospitalIdentifier]; route = mapService.Calculate(mdt.latitude, mdt.longitude, hospitalCoordinates.Latitude, hospitalCoordinates.Longitude); // mdt.SetToHospital(); SimulateMove(route, cancelToken, () => mdt.SetToHospital()); if (SimulatedEnvironment.PressAtHospitalButton(this)) { mdt.SetAtHospital(); } Thread.Sleep(TimeSpan.FromSeconds(5 * 60 / 10)); if (cancelToken.IsCancellationRequested == true) { Console.WriteLine("Task was cancelled."); cancelToken.ThrowIfCancellationRequested(); } // Move back to station Thread.Sleep(TimeSpan.FromSeconds(1 * 60 / 10)); BackToStation(cancelToken, hospitalCoordinates); }); var t = Task.Factory.StartNew(action, cancelToken); tasks.Add(t); }