From 851f1eff92bdaced77ba7fdeb51a3b12ba12d2e6 Mon Sep 17 00:00:00 2001 From: Ty Conner Date: Tue, 17 Dec 2024 02:49:11 -0500 Subject: [PATCH 1/5] Cache ServerVersion.AutoDetect Adjusted database connections so that they cache ServerVersion.AutoDetect result on first hit and reuse. This resolves a current bug that exhausts or times out connections to database. --- Source/ACE.Database/DatabaseManager.cs | 40 +++++++++++++++++++ .../ACE.Database/Models/Auth/AuthDbContext.cs | 2 +- .../Models/Shard/ShardDbContext.cs | 2 +- .../Models/World/WorldDbContext.cs | 2 +- 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/Source/ACE.Database/DatabaseManager.cs b/Source/ACE.Database/DatabaseManager.cs index 0c1288140b..ce00d4c9b2 100644 --- a/Source/ACE.Database/DatabaseManager.cs +++ b/Source/ACE.Database/DatabaseManager.cs @@ -1,5 +1,7 @@ using System; +using Microsoft.EntityFrameworkCore; + using log4net; namespace ACE.Database @@ -69,5 +71,43 @@ public static void Stop() if (serializedShardDb != null) serializedShardDb.Stop(); } + + private static ServerVersion authServerVersion; + private static ServerVersion shardServerVersion; + private static ServerVersion worldServerVersion; + public static ServerVersion CachedServerVersionAutoDetect(int database, string connectionString) + { + var serverVersion = database switch + { + 1 => authServerVersion, + 2 => shardServerVersion, + _ => worldServerVersion, + }; + + if (serverVersion != null) + return serverVersion; + + serverVersion = ServerVersion.AutoDetect(connectionString); + + //using var connection = new MySqlConnection( + // new MySqlConnectionStringBuilder(connectionString) + // { + // Database = string.Empty, + // AutoEnlist = false, + // //Pooling = false, + // }.ConnectionString); + //connection.Open(); + + //serverVersion = ServerVersion.Parse(connection.ServerVersion); + + if (database == 1) + authServerVersion = serverVersion; + else if (database == 2) + shardServerVersion = serverVersion; + else + worldServerVersion = serverVersion; + + return serverVersion; + } } } diff --git a/Source/ACE.Database/Models/Auth/AuthDbContext.cs b/Source/ACE.Database/Models/Auth/AuthDbContext.cs index 134fe9aeb7..0aa165872a 100644 --- a/Source/ACE.Database/Models/Auth/AuthDbContext.cs +++ b/Source/ACE.Database/Models/Auth/AuthDbContext.cs @@ -28,7 +28,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) var connectionString = $"server={config.Host};port={config.Port};user={config.Username};password={config.Password};database={config.Database};{config.ConnectionOptions}"; - optionsBuilder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString), builder => + optionsBuilder.UseMySql(connectionString, DatabaseManager.CachedServerVersionAutoDetect(1, connectionString), builder => { builder.EnableRetryOnFailure(10); }); diff --git a/Source/ACE.Database/Models/Shard/ShardDbContext.cs b/Source/ACE.Database/Models/Shard/ShardDbContext.cs index bceb8b1374..8e6ee0dbce 100644 --- a/Source/ACE.Database/Models/Shard/ShardDbContext.cs +++ b/Source/ACE.Database/Models/Shard/ShardDbContext.cs @@ -104,7 +104,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) var connectionString = $"server={config.Host};port={config.Port};user={config.Username};password={config.Password};database={config.Database};{config.ConnectionOptions}"; - optionsBuilder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString), builder => + optionsBuilder.UseMySql(connectionString, DatabaseManager.CachedServerVersionAutoDetect(2, connectionString), builder => { builder.EnableRetryOnFailure(10); }); diff --git a/Source/ACE.Database/Models/World/WorldDbContext.cs b/Source/ACE.Database/Models/World/WorldDbContext.cs index 38a4f1ff48..b206f4a904 100644 --- a/Source/ACE.Database/Models/World/WorldDbContext.cs +++ b/Source/ACE.Database/Models/World/WorldDbContext.cs @@ -132,7 +132,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) var connectionString = $"server={config.Host};port={config.Port};user={config.Username};password={config.Password};database={config.Database};{config.ConnectionOptions}"; - optionsBuilder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString), builder => + optionsBuilder.UseMySql(connectionString, DatabaseManager.CachedServerVersionAutoDetect(3, connectionString), builder => { builder.EnableRetryOnFailure(10); }); From b5827e9ac210ea24dc122a967a03caaac6fe503b Mon Sep 17 00:00:00 2001 From: Ty Conner Date: Tue, 17 Dec 2024 19:42:42 -0500 Subject: [PATCH 2/5] Change to dictionary --- Source/ACE.Database/DatabaseManager.cs | 36 ++++--------------- .../ACE.Database/Models/Auth/AuthDbContext.cs | 2 +- .../Models/Shard/ShardDbContext.cs | 2 +- .../Models/World/WorldDbContext.cs | 2 +- 4 files changed, 9 insertions(+), 33 deletions(-) diff --git a/Source/ACE.Database/DatabaseManager.cs b/Source/ACE.Database/DatabaseManager.cs index ce00d4c9b2..2e05bf3baa 100644 --- a/Source/ACE.Database/DatabaseManager.cs +++ b/Source/ACE.Database/DatabaseManager.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Microsoft.EntityFrameworkCore; @@ -72,40 +73,15 @@ public static void Stop() serializedShardDb.Stop(); } - private static ServerVersion authServerVersion; - private static ServerVersion shardServerVersion; - private static ServerVersion worldServerVersion; - public static ServerVersion CachedServerVersionAutoDetect(int database, string connectionString) - { - var serverVersion = database switch - { - 1 => authServerVersion, - 2 => shardServerVersion, - _ => worldServerVersion, - }; + private static readonly Dictionary cachedServerVersions = new(); - if (serverVersion != null) - return serverVersion; + public static ServerVersion CachedServerVersionAutoDetect(string database, string connectionString) + { + if (cachedServerVersions.TryGetValue(database, out ServerVersion serverVersion)) { return serverVersion; } serverVersion = ServerVersion.AutoDetect(connectionString); - //using var connection = new MySqlConnection( - // new MySqlConnectionStringBuilder(connectionString) - // { - // Database = string.Empty, - // AutoEnlist = false, - // //Pooling = false, - // }.ConnectionString); - //connection.Open(); - - //serverVersion = ServerVersion.Parse(connection.ServerVersion); - - if (database == 1) - authServerVersion = serverVersion; - else if (database == 2) - shardServerVersion = serverVersion; - else - worldServerVersion = serverVersion; + cachedServerVersions[database] = serverVersion; return serverVersion; } diff --git a/Source/ACE.Database/Models/Auth/AuthDbContext.cs b/Source/ACE.Database/Models/Auth/AuthDbContext.cs index 0aa165872a..560415adf9 100644 --- a/Source/ACE.Database/Models/Auth/AuthDbContext.cs +++ b/Source/ACE.Database/Models/Auth/AuthDbContext.cs @@ -28,7 +28,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) var connectionString = $"server={config.Host};port={config.Port};user={config.Username};password={config.Password};database={config.Database};{config.ConnectionOptions}"; - optionsBuilder.UseMySql(connectionString, DatabaseManager.CachedServerVersionAutoDetect(1, connectionString), builder => + optionsBuilder.UseMySql(connectionString, DatabaseManager.CachedServerVersionAutoDetect(config.Database, connectionString), builder => { builder.EnableRetryOnFailure(10); }); diff --git a/Source/ACE.Database/Models/Shard/ShardDbContext.cs b/Source/ACE.Database/Models/Shard/ShardDbContext.cs index 8e6ee0dbce..58b3919283 100644 --- a/Source/ACE.Database/Models/Shard/ShardDbContext.cs +++ b/Source/ACE.Database/Models/Shard/ShardDbContext.cs @@ -104,7 +104,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) var connectionString = $"server={config.Host};port={config.Port};user={config.Username};password={config.Password};database={config.Database};{config.ConnectionOptions}"; - optionsBuilder.UseMySql(connectionString, DatabaseManager.CachedServerVersionAutoDetect(2, connectionString), builder => + optionsBuilder.UseMySql(connectionString, DatabaseManager.CachedServerVersionAutoDetect(config.Database, connectionString), builder => { builder.EnableRetryOnFailure(10); }); diff --git a/Source/ACE.Database/Models/World/WorldDbContext.cs b/Source/ACE.Database/Models/World/WorldDbContext.cs index b206f4a904..3d112ca388 100644 --- a/Source/ACE.Database/Models/World/WorldDbContext.cs +++ b/Source/ACE.Database/Models/World/WorldDbContext.cs @@ -132,7 +132,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) var connectionString = $"server={config.Host};port={config.Port};user={config.Username};password={config.Password};database={config.Database};{config.ConnectionOptions}"; - optionsBuilder.UseMySql(connectionString, DatabaseManager.CachedServerVersionAutoDetect(3, connectionString), builder => + optionsBuilder.UseMySql(connectionString, DatabaseManager.CachedServerVersionAutoDetect(config.Database, connectionString), builder => { builder.EnableRetryOnFailure(10); }); From 218801d5b9f82b75e5f23b00e383528f23aeef5b Mon Sep 17 00:00:00 2001 From: Ty Conner Date: Tue, 17 Dec 2024 20:48:42 -0500 Subject: [PATCH 3/5] Update Source/ACE.Database/DatabaseManager.cs Co-authored-by: gmriggs --- Source/ACE.Database/DatabaseManager.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/ACE.Database/DatabaseManager.cs b/Source/ACE.Database/DatabaseManager.cs index 2e05bf3baa..442968f646 100644 --- a/Source/ACE.Database/DatabaseManager.cs +++ b/Source/ACE.Database/DatabaseManager.cs @@ -77,13 +77,13 @@ public static void Stop() public static ServerVersion CachedServerVersionAutoDetect(string database, string connectionString) { - if (cachedServerVersions.TryGetValue(database, out ServerVersion serverVersion)) { return serverVersion; } - - serverVersion = ServerVersion.AutoDetect(connectionString); - - cachedServerVersions[database] = serverVersion; - + if (!cachedServerVersions.TryGetValue(database, out ServerVersion serverVersion)) + { + serverVersion = ServerVersion.AutoDetect(connectionString); + cachedServerVersions[database] = serverVersion; + } return serverVersion; + } } } From 919d11cf215566e8c7fb2a3f4b5ecae41dee326a Mon Sep 17 00:00:00 2001 From: Ty Conner Date: Tue, 17 Dec 2024 20:50:17 -0500 Subject: [PATCH 4/5] Update DatabaseManager.cs --- Source/ACE.Database/DatabaseManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/ACE.Database/DatabaseManager.cs b/Source/ACE.Database/DatabaseManager.cs index 442968f646..b9d989d308 100644 --- a/Source/ACE.Database/DatabaseManager.cs +++ b/Source/ACE.Database/DatabaseManager.cs @@ -1,5 +1,5 @@ using System; -using System.Collections.Generic; +using System.Collections.Concurrent; using Microsoft.EntityFrameworkCore; @@ -73,7 +73,7 @@ public static void Stop() serializedShardDb.Stop(); } - private static readonly Dictionary cachedServerVersions = new(); + private static readonly ConcurrentDictionary cachedServerVersions = new(); public static ServerVersion CachedServerVersionAutoDetect(string database, string connectionString) { From aa92c1d60bae6b5d810db7c5c5689c5d82f721e2 Mon Sep 17 00:00:00 2001 From: Ty Conner Date: Tue, 17 Dec 2024 21:01:32 -0500 Subject: [PATCH 5/5] Update DatabaseManager.cs --- Source/ACE.Database/DatabaseManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/ACE.Database/DatabaseManager.cs b/Source/ACE.Database/DatabaseManager.cs index b9d989d308..50cee2c1bd 100644 --- a/Source/ACE.Database/DatabaseManager.cs +++ b/Source/ACE.Database/DatabaseManager.cs @@ -83,7 +83,6 @@ public static ServerVersion CachedServerVersionAutoDetect(string database, strin cachedServerVersions[database] = serverVersion; } return serverVersion; - } } }