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

View file

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
@ -15,7 +16,17 @@ namespace NucuCar.Sensors
Host.CreateDefaultBuilder(args) Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) => .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>(); services.AddHostedService<EnvironmentSensor.BackgroundWorker>();
}) })
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<GrpcStartup>(); }); .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);
}
}
}
}