using InfluxDB.Client; using Managing.Infrastructure.Databases.InfluxDb.Abstractions; namespace Managing.Infrastructure.Databases.InfluxDb; public class InfluxDbRepository : IInfluxDbRepository, IDisposable { private readonly string _token; private readonly string _url; private readonly InfluxDBClient _client; private readonly WriteApi _writeApi; private readonly QueryApi _queryApi; private readonly SemaphoreSlim _writeSemaphore = new SemaphoreSlim(1, 1); private readonly SemaphoreSlim _querySemaphore = new SemaphoreSlim(1, 1); private bool _disposed = false; public string Organization { get; set; } public InfluxDbRepository(IInfluxDbSettings settings) { _token = settings.Token; _url = settings.Url; Organization = settings.Organization; // Create a single client instance that will be reused _client = new InfluxDBClient(_url, _token); _writeApi = _client.GetWriteApi(); _queryApi = _client.GetQueryApi(); } public void Write(Action action) { if (_disposed) throw new ObjectDisposedException(nameof(InfluxDbRepository)); _writeSemaphore.Wait(); try { action(_writeApi); } finally { _writeSemaphore.Release(); } } public async Task WriteAsync(Func action) { if (_disposed) throw new ObjectDisposedException(nameof(InfluxDbRepository)); await _writeSemaphore.WaitAsync(); try { await action(_writeApi); } finally { _writeSemaphore.Release(); } } public async Task QueryAsync(Func> action) { if (_disposed) throw new ObjectDisposedException(nameof(InfluxDbRepository)); await _querySemaphore.WaitAsync(); try { return await action(_queryApi); } finally { _querySemaphore.Release(); } } public void Dispose() { if (!_disposed) { try { // Give the WriteApi time to flush any pending writes _writeApi?.Dispose(); } catch (Exception) { // Ignore disposal errors } try { _client?.Dispose(); } catch (Exception) { // Ignore disposal errors } _writeSemaphore?.Dispose(); _querySemaphore?.Dispose(); _disposed = true; } } }