public void Add(int key, CarInformation value) { _cacheLock.EnterWriteLock(); try { _innerCache.Add(key, value); } finally { _cacheLock.ExitWriteLock(); } }
public AddOrUpdateStatus AddOrUpdate(int key, CarInformation value) { _cacheLock.EnterUpgradeableReadLock(); try { if (_innerCache.TryGetValue(key, out var result)) { if (result == value) { return(AddOrUpdateStatus.Unchanged); } else { _cacheLock.EnterWriteLock(); try { _innerCache[key] = value; } finally { _cacheLock.ExitWriteLock(); } return(AddOrUpdateStatus.Updated); } } else { _cacheLock.EnterWriteLock(); try { _innerCache.Add(key, value); } finally { _cacheLock.ExitWriteLock(); } return(AddOrUpdateStatus.Added); } } finally { _cacheLock.ExitUpgradeableReadLock(); } }
public bool AddWithTimeout(int key, CarInformation value, int timeout) { if (_cacheLock.TryEnterWriteLock(timeout)) { try { _innerCache.Add(key, value); } finally { _cacheLock.ExitWriteLock(); } return(true); } else { return(false); } }
/// <summary> /// Get the last known location and calculate speed. Then Publish back to the MQTT Broker. /// </summary> /// <param name="mqttClient">The MQTT Client</param> /// <param name="topic">The most recent topic</param> /// <returns>A Task which performs the operation</returns> public async Task Work(IManagedMqttClient mqttClient, CarCoordinates topic) { try { // Get lastCoordinate from key var carInformation = _carCache.Read(topic.CarIndex); // Get Geo coordinate var lastGeoCoordinate = new GeoCoordinate(carInformation.LastLocation.Latitude, carInformation.LastLocation.Longitude); var currentGeoCoordinate = new GeoCoordinate(topic.Location.Latitude, topic.Location.Longitude); // Calculate the distance and the speed var distance = lastGeoCoordinate.GetDistanceTo(currentGeoCoordinate); var speed = Speedometer.CalculateSpeedMph(distance, carInformation.LastRecordedTimestamp, topic.TimeStamp); // using the total distance driven var carValues = _carCache.Values().ToList(); var position = carValues.OrderByDescending(x => x.TotalDistanceTraveled) .Select(x => x.CarIndex).ToList().IndexOf(topic.CarIndex) + 1; // has the car position changed if (position != carInformation.Position) { // who is now in that position? var carInPreviousPos = carValues.FirstOrDefault(x => x.Position == position); if (carInPreviousPos != null) { var eventStatus = new EventMessage() { Timestamp = topic.TimeStamp, Text = $"Car {carInPreviousPos.CarIndex} races ahead of Car {carInformation.CarIndex} in a dramatic overtake." }; var messageEvent = MessageBuilder.CreateMessage(eventStatus); // send event for the overtake await mqttClient.PublishAsync(messageEvent); } } // Set information car information carInformation.TotalDistanceTraveled += distance; carInformation.LastRecordedTimestamp = topic.TimeStamp; carInformation.LastLocation = topic.Location; carInformation.Position = position; _carCache.AddOrUpdate(topic.CarIndex, carInformation); // The response var messageSpeed = MessageBuilder.CreateMessage(CarStatus.SpeedStatus(topic, speed)); var messagePosition = MessageBuilder.CreateMessage(CarStatus.PositionStatus(topic, position)); await mqttClient.PublishAsync(messageSpeed); await mqttClient.PublishAsync(messagePosition); } catch (KeyNotFoundException) { // Must be first time round, add topic to dictionary var carInformation = new CarInformation() { LastLocation = topic.Location, LastRecordedTimestamp = topic.TimeStamp, Position = 0, TotalDistanceTraveled = 0, CarIndex = topic.CarIndex }; _carCache.AddOrUpdate(topic.CarIndex, carInformation); } catch (Exception ex) { _logger.LogError(ex.ToString()); } }