Refactor NucuCar.Sensors to use DI Singleton instead of handmade one

This commit is contained in:
Denis-Cosmin Nutiu 2019-11-24 17:47:17 +02:00
parent ec90c361ad
commit fab4127ace
7 changed files with 87 additions and 104 deletions

View file

@ -3,6 +3,7 @@ using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NucuCar.Domain.Telemetry;
using NucuCar.Sensors.Telemetry;
using NucuCarSensorsProto;
@ -18,14 +19,17 @@ namespace NucuCar.Sensors.EnvironmentSensor
private readonly bool _telemetryEnabled;
private readonly int _measurementDelay;
private readonly ILogger<BackgroundWorker> _logger;
private readonly TelemetryPublisher _telemetryPublisher;
public BackgroundWorker(ILogger<BackgroundWorker> logger, IConfiguration config)
public BackgroundWorker(ILogger<BackgroundWorker> logger, IConfiguration config,
SensorTelemetry sensorTelemetry)
{
_logger = logger;
_serviceEnabled = config.GetValue<bool>("EnvironmentSensor:Enabled");
_telemetryEnabled = config.GetValue<bool>("EnvironmentSensor:Telemetry");
_measurementDelay = config.GetValue<int>("EnvironmentSensor:MeasurementInterval");
_telemetryPublisher = sensorTelemetry.Publisher;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
@ -40,26 +44,27 @@ namespace NucuCar.Sensors.EnvironmentSensor
sensor.InitializeSensor();
if (_telemetryEnabled)
{
SensorTelemetryPublisher.Instance.RegisterTelemeter(sensor);
_telemetryPublisher?.RegisterTelemeter(sensor);
}
while (!stoppingToken.IsCancellationRequested)
{
/* If sensor is ok attempt to read. */
if (sensor.GetState() == SensorStateEnum.Initialized)
{
await sensor.TakeMeasurement();
}
/* Else attempt to re-initialize. */
else
{
await Task.Delay(10000, stoppingToken);
/* Attempt to reinitialize the sensor. */
sensor.InitializeSensor();
}
await Task.Delay(_measurementDelay, stoppingToken);
}
SensorTelemetryPublisher.Instance.UnRegisterTelemeter(sensor);
_telemetryPublisher?.UnRegisterTelemeter(sensor);
}
}
}

View file

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
@ -15,7 +16,17 @@ namespace NucuCar.Sensors
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Telemetry.BackgroundWorker>();
var config = hostContext.Configuration;
// Singletons
services.AddSingleton<Telemetry.SensorTelemetry>();
// Workers
if (config.GetValue<bool>("Telemetry:Enabled"))
{
services.AddHostedService<Telemetry.TelemetryBackgroundWorker>();
}
services.AddHostedService<EnvironmentSensor.BackgroundWorker>();
})
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<GrpcStartup>(); });

View file

@ -1,55 +0,0 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace NucuCar.Sensors.Telemetry
{
/// <summary>
/// Telemetry service, which pools the telemetry sources and pushes telemetry data to the cloud.
/// </summary>
public class BackgroundWorker : BackgroundService
{
private readonly bool _serviceEnabled;
private readonly int _interval;
private readonly ILogger _logger;
public BackgroundWorker(ILogger<BackgroundWorker> logger, IConfiguration configuration)
{
_logger = logger;
_serviceEnabled = configuration.GetValue<bool>("Telemetry:Enabled");
_interval = configuration.GetValue<int>("Telemetry:Interval");
var connectionString = configuration.GetValue<string>("Telemetry:ConnectionString");
if (_serviceEnabled)
{
SensorTelemetryPublisher.CreateSingleton(connectionString, "NucuCar.Sensors", logger);
}
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
if (!_serviceEnabled)
{
return;
}
await Task.Delay(_interval, stoppingToken);
var telemetryService = SensorTelemetryPublisher.Instance;
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Publishing telemetry data!");
await telemetryService.PublishAsync(stoppingToken);
await Task.Delay(_interval, stoppingToken);
}
}
public override void Dispose()
{
base.Dispose();
SensorTelemetryPublisher.Instance?.Dispose();
}
}
}

View file

@ -0,0 +1,28 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using NucuCar.Domain.Telemetry;
namespace NucuCar.Sensors.Telemetry
{
public class SensorTelemetry
{
public TelemetryPublisher Publisher { get; }
public SensorTelemetry(ILogger<SensorTelemetry> logger, IConfiguration configuration)
{
if (configuration.GetValue<bool>("Telemetry:Enabled"))
{
Publisher = new TelemetryPublisherAzure(new TelemetryPublisherBuilderOptions()
{
ConnectionString = configuration.GetValue<string>("Telemetry:ConnectionString"),
TelemetrySource = "NucuCar.Sensors",
Logger = logger
});
}
else
{
Publisher = null;
}
}
}
}

View file

@ -1,44 +0,0 @@
using System;
using Microsoft.Extensions.Logging;
using NucuCar.Domain.Telemetry;
namespace NucuCar.Sensors.Telemetry
{
public class SensorTelemetryPublisher : IDisposable
{
private static object _palock = new object();
public static TelemetryPublisher Instance { get; private set; }
/// <summary>
/// Creates a telemetry publisher instance see <see cref="TelemetryPublisher"/>.
/// </summary>
public static TelemetryPublisher CreateSingleton(string connectionString, string telemetrySource,
ILogger logger)
{
lock (_palock)
{
if (Instance != null) return Instance;
var telemetryPublisher =
TelemetryPublisherAzure.CreateFromConnectionString(connectionString, telemetrySource, logger);
Instance = telemetryPublisher;
return Instance;
}
}
private static void ReleaseUnmanagedResources()
{
Instance?.Dispose();
}
public void Dispose()
{
ReleaseUnmanagedResources();
GC.SuppressFinalize(this);
}
~SensorTelemetryPublisher()
{
ReleaseUnmanagedResources();
}
}
}

View file

@ -0,0 +1,38 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NucuCar.Domain.Telemetry;
namespace NucuCar.Sensors.Telemetry
{
/// <summary>
/// Telemetry service, which pools the telemetry sources and pushes telemetry data to the cloud.
/// </summary>
public class TelemetryBackgroundWorker : BackgroundService
{
private readonly int _interval;
private readonly ILogger _logger;
private readonly SensorTelemetry _sensorTelemetry;
public TelemetryBackgroundWorker(ILogger<TelemetryBackgroundWorker> logger, IConfiguration configuration,
SensorTelemetry sensorTelemetry)
{
_logger = logger;
_interval = configuration.GetValue<int>("Telemetry:Interval");
_sensorTelemetry = sensorTelemetry;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await Task.Delay(_interval, stoppingToken);
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Is publishing telemetry data!");
await _sensorTelemetry.Publisher.PublishAsync(stoppingToken);
await Task.Delay(_interval, stoppingToken);
}
}
}
}