using System; using MySqlConnector; using Serilog; namespace SyncEngine.MySql { public sealed class MySqlConnectionHolder : IDisposable { private readonly MySqlConnectionFactory _factory; private readonly ILogger _logger; private MySqlConnection _connection; private bool _connectionLost; public MySqlConnectionHolder(MySqlConnectionFactory factory, ILogger logger) { _factory = factory; _logger = logger; } public MySqlConnection Connection { get { if (_connection == null) { throw new InvalidOperationException("MySQL connection is not open."); } return _connection; } } public void EnsureConnected() { if (_connection != null && _connection.State == System.Data.ConnectionState.Open) { return; } OpenConnection(logRegained: _connectionLost); } public void Reconnect() { _logger.Warning("MySQL connection lost; reconnecting..."); _connectionLost = true; OpenConnection(logRegained: true); } public void Dispose() { DisposeConnection(); } private void OpenConnection(bool logRegained) { DisposeConnection(); var conn = _factory.Create(); try { conn.Open(); _connection = conn; if (logRegained) { _logger.Information("MySQL connection regained"); _connectionLost = false; } } catch { conn.Dispose(); throw; } } private void DisposeConnection() { if (_connection == null) { return; } _connection.Dispose(); _connection = null; } } }