static MySqlXConnectionStringBuilder() { // Server options. Options.Add(new MySqlConnectionStringOption("connect-timeout", "connecttimeout", typeof(uint), (uint)10000, false, delegate(MySqlXConnectionStringBuilder msb, MySqlConnectionStringOption sender, object Value) { sender.ValidateValue(ref Value, sender.Keyword); uint value = (uint)Convert.ChangeType(Value, sender.BaseType); // Timeout in milliseconds should not exceed maximum for 32 bit // signed integer (~24 days). We truncate the value if it exceeds // maximum (MySqlCommand.CommandTimeout uses the same technique) uint timeout = Math.Min(value, Int32.MaxValue); if (timeout != value) { MySqlTrace.LogWarning(-1, "Connection timeout value too large (" + value + " milliseconds). Changed to max. possible value " + +timeout + " milliseconds)"); } msb.SetValue("connect-timeout", timeout); }, (msb, sender) => (uint)msb.values["connect-timeout"] )); Options.Add(new MySqlConnectionStringOption("connection-attributes", "connectionattributes", typeof(string), "true", false)); // Authentication options. Options.Add(new MySqlConnectionStringOption("auth", null, typeof(MySqlAuthenticationMode), MySqlAuthenticationMode.Default, false)); Options.Add(new MySqlConnectionStringOption("sslcrl", "ssl-crl", typeof(string), null, false, (msb, sender, value) => { msb.SslCrl = value as string; }, ((msb, sender) => { return(msb.SslCrl); }))); }
/// <summary> /// Loads the libzstd.dll assembly. /// </summary> internal static void LoadLibzstdLibrary() { // If the library has already been loaded, there is no need to load it again. if (LibZstdLoaded != null) { return; } // Attempt to load the library from an embedded resource. LibZstdLoaded = UnmanagedLibraryLoader.LoadUnmanagedLibraryFromEmbeddedResources("MySql.Data", "libzstd.dll"); // If loading from an embedded resource fails, attempt to load it from a file in the output folder. if (LibZstdLoaded == false) { ZstandardInterop.LoadLibzstdLibrary(string.Empty); try { // Creating this temporary stream to check if the library was loaded succesfully. using (var testStream = new ZstandardStream(new MemoryStream(), CompressionMode.Compress)) { } LibZstdLoaded = true; } catch {} } // If all attempts fail, log a warning and update the client supported compression algorithms. if (LibZstdLoaded == false) { MySqlTrace.LogWarning(-1, ResourcesX.CompressionFailedToLoadLibzstdAssembly); } }
/// <summary> /// Negotiates compression capabilities with the server. /// </summary> /// <param name="serverSupportedAlgorithms">An array containing the compression algorithms supported by the server.</param> /// <param name="clientAgainstUserAlgorithms">An array containing the compression algorithms given by user/client.</param> private Dictionary <string, object> NegotiateCompression(string[] serverSupportedAlgorithms, string[] clientAgainstUserAlgorithms) { if (serverSupportedAlgorithms == null || serverSupportedAlgorithms.Length == 0) { if (Settings.Compression == CompressionType.Required && clientAgainstUserAlgorithms.Length > 0) { throw new NotSupportedException(ResourcesX.CompressionAlgorithmNegotiationFailed); } return(null); } // If server and client don't have matching compression algorithms either log a warning message // or raise an exception based on the selected compression type. XCompressionController.LoadLibzstdLibrary(); if (!clientAgainstUserAlgorithms.Any(element => serverSupportedAlgorithms.Contains(element))) { if (Settings.Compression == CompressionType.Preferred) { MySqlTrace.LogWarning(-1, ResourcesX.CompressionAlgorithmNegotiationFailed); return(null); } else if (Settings.Compression == CompressionType.Required) { throw new NotSupportedException(ResourcesX.CompressionAlgorithmNegotiationFailed); } } string negotiatedAlgorithm = null; for (int index = 0; index < clientAgainstUserAlgorithms.Length; index++) { if (!serverSupportedAlgorithms.Contains(clientAgainstUserAlgorithms[index])) { continue; } negotiatedAlgorithm = clientAgainstUserAlgorithms[index]; break; } if (negotiatedAlgorithm == null) { return(null); } // Create the compression capability object. var compressionCapabilities = new Dictionary <string, object>(); compressionCapabilities.Add(XCompressionController.ALGORITHMS_SUBKEY, negotiatedAlgorithm); compressionCapabilities.Add(XCompressionController.SERVER_COMBINE_MIXED_MESSAGES_SUBKEY, XCompressionController.DEFAULT_SERVER_COMBINE_MIXED_MESSAGES_VALUE); // TODO: For future use. //compressionCapabilities.Add(XCompressionController.SERVER_MAX_COMBINE_MESSAGES_SUBKEY, XCompressionController.DEFAULT_SERVER_MAX_COMBINE_MESSAGES_VALUE); return(compressionCapabilities); }
/// <summary> /// Handles a failed connection to a server. /// </summary> /// <param name="server">The failed server.</param> /// <remarks>This method can be overrided to implement a custom failover handling.</remarks> internal protected virtual void HandleFailover(ReplicationServer server) { BackgroundWorker worker = new BackgroundWorker(); worker.DoWork += delegate(object sender, DoWorkEventArgs e) { bool isRunning = false; ReplicationServer server1 = e.Argument as ReplicationServer; System.Timers.Timer timer = new System.Timers.Timer(RetryTime * 1000.0); System.Timers.ElapsedEventHandler elapsedEvent = delegate(object sender1, System.Timers.ElapsedEventArgs e1) { if (isRunning) { return; } try { isRunning = true; using (MySqlConnection connectionFailed = new MySqlConnection(server.ConnectionString)) { connectionFailed.Open(); server1.IsAvailable = true; timer.Stop(); } } catch { MySqlTrace.LogWarning(0, string.Format(Resources.Replication_ConnectionAttemptFailed, server1.Name)); } finally { isRunning = false; } }; timer.Elapsed += elapsedEvent; timer.Start(); elapsedEvent(sender, null); }; worker.RunWorkerAsync(server); }
/// <summary> /// Assigns a new server driver to the connection object /// </summary> /// <param name="groupName">Group name</param> /// <param name="master">True if the server connection to assign must be a master</param> /// <param name="connection">MySqlConnection object where the new driver will be assigned</param> public static void GetNewConnection(string groupName, bool master, MySqlConnection connection) { do { if (!IsReplicationGroup(groupName)) { return; } ReplicationServerGroup group = GetGroup(groupName); ReplicationServer server = group.GetServer(master); if (server == null) { throw new MySqlException(Properties.Resources.Replication_NoAvailableServer); } Driver driver = Driver.Create(new MySqlConnectionStringBuilder(server.ConnectionString)); if (connection.driver == null || driver.Settings.ConnectionString != connection.driver.Settings.ConnectionString) { connection.Close(); connection.hasBeenOpen = false; try { connection.driver = driver; connection.Open(); return; } catch (Exception) { // retry to open a failed connection and update its status connection.driver = null; server.IsAvailable = false; BackgroundWorker worker = new BackgroundWorker(); worker.DoWork += delegate(object sender, DoWorkEventArgs e) { bool isRunning = false; ReplicationServer server1 = e.Argument as ReplicationServer; int retryTime = ReplicationManager.GetGroup(groupName).RetryTime; #if !RT System.Timers.Timer timer = new System.Timers.Timer(retryTime * 1000.0); System.Timers.ElapsedEventHandler elapsedEvent = delegate(object sender1, System.Timers.ElapsedEventArgs e1) { if (isRunning) { return; } try { isRunning = true; using (MySqlConnection connectionFailed = new MySqlConnection(server.ConnectionString)) { connectionFailed.Open(); server1.IsAvailable = true; timer.Stop(); } } catch { MySqlTrace.LogWarning(0, string.Format(Properties.Resources.Replication_ConnectionAttemptFailed, server1.Name)); } finally { isRunning = false; } }; timer.Elapsed += elapsedEvent; timer.Start(); elapsedEvent(sender, null); #else Windows.UI.Xaml.DispatcherTimer timer = new Windows.UI.Xaml.DispatcherTimer(); TimeSpan ts = new TimeSpan(retryTime * 1000); System.EventHandler <object> elapsedEvent = (TickSender, TickEventArgs) => { if (isRunning) { return; } try { isRunning = true; using (MySqlConnection connectionFailed = new MySqlConnection(server.ConnectionString)) { connectionFailed.Open(); server1.IsAvailable = true; timer.Stop(); } } catch { MySqlTrace.LogWarning(0, string.Format(Properties.Resources.Replication_ConnectionAttemptFailed, server1.Name)); } finally { isRunning = false; } }; timer.Tick += elapsedEvent; elapsedEvent(sender, null); timer.Start(); #endif }; worker.RunWorkerAsync(server); } } else { return; } } while (true); }
public static void GetNewConnection(string groupName, bool master, MySqlConnection connection) { while (true) { if (!ReplicationManager.IsReplicationGroup(groupName)) { break; } ReplicationServerGroup group = ReplicationManager.GetGroup(groupName); ReplicationServer server = group.GetServer(master); if (server == null) { goto Block_2; } Driver driver = Driver.Create(new MySqlConnectionStringBuilder(server.ConnectionString)); if (connection.driver == null || driver.Settings.ConnectionString != connection.driver.Settings.ConnectionString) { connection.Close(); connection.hasBeenOpen = false; try { connection.driver = driver; connection.Open(); } catch (Exception) { connection.driver = null; server.IsAvailable = false; BackgroundWorker backgroundWorker = new BackgroundWorker(); backgroundWorker.DoWork += delegate(object sender, DoWorkEventArgs e) { bool isRunning = false; ReplicationServer server1 = e.Argument as ReplicationServer; int retryTime = ReplicationManager.GetGroup(groupName).RetryTime; Timer timer = new Timer((double)retryTime * 1000.0); ElapsedEventHandler elapsedEventHandler = delegate(object sender1, ElapsedEventArgs e1) { if (isRunning) { return; } try { isRunning = true; using (MySqlConnection mySqlConnection = new MySqlConnection(server.ConnectionString)) { mySqlConnection.Open(); server1.IsAvailable = true; timer.Stop(); } } catch { MySqlTrace.LogWarning(0, string.Format(Resources.Replication_ConnectionAttemptFailed, server1.Name)); } finally { isRunning = false; } }; timer.Elapsed += elapsedEventHandler; timer.Start(); elapsedEventHandler(sender, null); }; backgroundWorker.RunWorkerAsync(server); continue; } return; } return; } return; Block_2: throw new MySqlException(Resources.Replication_NoAvailableServer); }
/// <summary> /// Handles a failed connection to a server. /// </summary> /// <param name="server">The failed server.</param> /// <remarks>This method can be overrided to implement a custom failover handling.</remarks> internal protected virtual void HandleFailover(ReplicationServer server) { BackgroundWorker worker = new BackgroundWorker(); worker.DoWork += delegate(object sender, DoWorkEventArgs e) { bool isRunning = false; ReplicationServer server1 = e.Argument as ReplicationServer; #if !NETSTANDARD1_3 System.Timers.Timer timer = new System.Timers.Timer(RetryTime * 1000.0); System.Timers.ElapsedEventHandler elapsedEvent = delegate(object sender1, System.Timers.ElapsedEventArgs e1) { if (isRunning) { return; } try { isRunning = true; using (MySqlConnection connectionFailed = new MySqlConnection(server.ConnectionString)) { connectionFailed.Open(); server1.IsAvailable = true; timer.Stop(); } } catch { MySqlTrace.LogWarning(0, string.Format(Resources.Replication_ConnectionAttemptFailed, server1.Name)); } finally { isRunning = false; } }; timer.Elapsed += elapsedEvent; timer.Start(); elapsedEvent(sender, null); #else Windows.UI.Xaml.DispatcherTimer timer = new Windows.UI.Xaml.DispatcherTimer(); TimeSpan ts = new TimeSpan(RetryTime * 1000); System.EventHandler <object> elapsedEvent = (TickSender, TickEventArgs) => { if (isRunning) { return; } try { isRunning = true; using (MySqlConnection connectionFailed = new MySqlConnection(server.ConnectionString)) { connectionFailed.Open(); server1.IsAvailable = true; timer.Stop(); } } catch { MySqlTrace.LogWarning(0, string.Format(Properties.Resources.Replication_ConnectionAttemptFailed, server1.Name)); } finally { isRunning = false; } }; timer.Tick += elapsedEvent; elapsedEvent(sender, null); timer.Start(); #endif }; worker.RunWorkerAsync(server); }