diff --git a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj index cae1e96b9..8768ecd17 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj +++ b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj @@ -11,13 +11,13 @@ Haiping Chen SciSharp STACK - LL Application Framework + AI Agent Application Framework Open source LLM application framework to build scalable, flexible and robust AI system. git https://github.com/SciSharp/BotSharp - Chatbot, Bot, LLM, AI, ChatGPT, OpenAI + Chatbot, Agent, LLM, AI, ChatGPT, OpenAI, Semantic Support dialogue status tracking. Since 2018 Haiping Chen https://github.com/SciSharp/BotSharp @@ -177,12 +177,12 @@ + - + - - + diff --git a/src/Infrastructure/BotSharp.Core/Infrastructures/DistributedLocker.cs b/src/Infrastructure/BotSharp.Core/Infrastructures/DistributedLocker.cs index 82b655c79..0a5a7cb82 100644 --- a/src/Infrastructure/BotSharp.Core/Infrastructures/DistributedLocker.cs +++ b/src/Infrastructure/BotSharp.Core/Infrastructures/DistributedLocker.cs @@ -1,6 +1,4 @@ -using RedLockNet; -using RedLockNet.SERedis; -using RedLockNet.SERedis.Configuration; +using Medallion.Threading.Redis; using StackExchange.Redis; namespace BotSharp.Core.Infrastructures; @@ -8,42 +6,46 @@ namespace BotSharp.Core.Infrastructures; public class DistributedLocker { private readonly BotSharpDatabaseSettings _settings; - private readonly RedLockFactory _lockFactory; - public DistributedLocker(/*BotSharpDatabaseSettings settings*/) + public DistributedLocker(BotSharpDatabaseSettings settings) { - // _settings = settings; + _settings = settings; + } + + public async Task Lock(string resource, Func action, int timeoutInSeconds = 30) + { + var timeout = TimeSpan.FromSeconds(timeoutInSeconds); - var multiplexers = new List(); - foreach (var x in "".Split(';')) + var connection = await ConnectionMultiplexer.ConnectAsync(_settings.Redis); + var @lock = new RedisDistributedLock(resource, connection.GetDatabase()); + await using (var handle = await @lock.TryAcquireAsync(timeout)) { - var option = new ConfigurationOptions + if (handle != null) + { + await action(); + } + else { - AbortOnConnectFail = false, - EndPoints = { x } - }; - var _connMuliplexer = ConnectionMultiplexer.Connect(option); - multiplexers.Add(_connMuliplexer); + Serilog.Log.Logger.Error($"Acquire lock for {resource} failed due to after {timeout}s timeout."); + } } - - _lockFactory = RedLockFactory.Create(multiplexers); } - public async Task Lock(string resource, Func action) + public async Task Lock(string resource, Action action, int timeoutInSeconds = 30) { - var expiry = TimeSpan.FromSeconds(60); - var wait = TimeSpan.FromSeconds(30); - var retry = TimeSpan.FromSeconds(3); + var timeout = TimeSpan.FromSeconds(timeoutInSeconds); - await using (var redLock = await _lockFactory.CreateLockAsync(resource, expiry, wait, retry)) + var connection = await ConnectionMultiplexer.ConnectAsync(_settings.Redis); + var @lock = new RedisDistributedLock(resource, connection.GetDatabase()); + await using (var handle = await @lock.TryAcquireAsync(timeout)) { - if (redLock.IsAcquired) + if (handle != null) { - await action(); + action(); } else { - Console.WriteLine($"Acquire locak failed due to {resource} after {wait}s timeout."); + Serilog.Log.Logger.Error($"Acquire lock for {resource} failed due to after {timeout}s timeout."); } } } diff --git a/src/Infrastructure/BotSharp.Core/Repository/RepositoryPlugin.cs b/src/Infrastructure/BotSharp.Core/Repository/RepositoryPlugin.cs index 3160597a5..bfbc0a6da 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/RepositoryPlugin.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/RepositoryPlugin.cs @@ -12,6 +12,9 @@ public class RepositoryPlugin : IBotSharpPlugin public void RegisterDI(IServiceCollection services, IConfiguration config) { + var myDatabaseSettings = new BotSharpDatabaseSettings(); + config.Bind("Database", myDatabaseSettings); + // In order to use EntityFramework.BootKit in other plugin services.AddScoped(provider => { @@ -25,14 +28,8 @@ public void RegisterDI(IServiceCollection services, IConfiguration config) return settingService.Bind("Database"); }); - services.AddScoped(provider => - { - var settingService = provider.GetRequiredService(); - return settingService.Bind("Database"); - }); + services.AddSingleton(provider => myDatabaseSettings); - var myDatabaseSettings = new BotSharpDatabaseSettings(); - config.Bind("Database", myDatabaseSettings); if (myDatabaseSettings.Default == RepositoryEnum.FileRepository) { services.AddScoped();