DistributedLocker

This commit is contained in:
Haiping Chen 2024-04-30 07:50:01 -05:00
parent 5604273d1d
commit 1cfa6a8618
9 changed files with 84 additions and 18 deletions

View file

@ -25,5 +25,5 @@ public interface IWebBrowser
Task CloseBrowser(string contextId);
Task CloseCurrentPage(string contextId);
Task<BrowserActionResult> SendHttpRequest(string contextId, HttpRequestParams actionParams);
Task<string> GetAttributeValue(MessageInfo message, ElementLocatingArgs location, BrowserActionResult result);
Task<BrowserActionResult> GetAttributeValue(MessageInfo message, ElementLocatingArgs location);
}

View file

@ -4,24 +4,29 @@ namespace BotSharp.Abstraction.Browsing.Models;
public class ElementActionArgs
{
private BroswerActionEnum _action;
public BroswerActionEnum Action => _action;
public BroswerActionEnum Action { get; set; }
private string? _content;
public string? Content => _content;
public string? Content { get; set; }
private ElementPosition? _position;
public ElementPosition? Position => _position;
public ElementPosition? Position { get; set; }
/// <summary>
/// Required for deserialization
/// </summary>
public ElementActionArgs()
{
}
public ElementActionArgs(BroswerActionEnum action, ElementPosition? position = null)
{
_action = action;
_position = position;
Action = action;
Position = position;
}
public ElementActionArgs(BroswerActionEnum action, string content)
{
_action = action;
_content = content;
Action = action;
Content = content;
}
}

View file

@ -7,6 +7,7 @@ public class BotSharpDatabaseSettings : DatabaseBasicSettings
public string BotSharpMongoDb { get; set; }
public string TablePrefix { get; set; }
public DbConnectionSetting BotSharp { get; set; }
public string Redis { get; set; }
}
public class DatabaseBasicSettings

View file

@ -152,6 +152,7 @@
<PackageReference Include="EntityFrameworkCore.BootKit" Version="8.2.1" />
<PackageReference Include="Fluid.Core" Version="2.8.0" />
<PackageReference Include="Nanoid" Version="3.0.0" />
<PackageReference Include="RedLock.net" Version="2.3.2" />
</ItemGroup>
<ItemGroup>

View file

@ -14,9 +14,11 @@ public static class BotSharpCoreExtensions
{
services.AddScoped<ISettingService, SettingService>();
services.AddScoped<IUserService, UserService>();
services.AddSingleton<DistributedLocker>();
RegisterPlugins(services, config);
ConfigureBotSharpOptions(services, configOptions);
return services;
}

View file

@ -0,0 +1,50 @@
using RedLockNet;
using RedLockNet.SERedis;
using RedLockNet.SERedis.Configuration;
using StackExchange.Redis;
namespace BotSharp.Core.Infrastructures;
public class DistributedLocker
{
private readonly BotSharpDatabaseSettings _settings;
private readonly RedLockFactory _lockFactory;
public DistributedLocker(/*BotSharpDatabaseSettings settings*/)
{
// _settings = settings;
var multiplexers = new List<RedLockMultiplexer>();
foreach (var x in "".Split(';'))
{
var option = new ConfigurationOptions
{
AbortOnConnectFail = false,
EndPoints = { x }
};
var _connMuliplexer = ConnectionMultiplexer.Connect(option);
multiplexers.Add(_connMuliplexer);
}
_lockFactory = RedLockFactory.Create(multiplexers);
}
public async Task Lock(string resource, Func<Task> action)
{
var expiry = TimeSpan.FromSeconds(60);
var wait = TimeSpan.FromSeconds(30);
var retry = TimeSpan.FromSeconds(3);
await using (var redLock = await _lockFactory.CreateLockAsync(resource, expiry, wait, retry))
{
if (redLock.IsAcquired)
{
await action();
}
else
{
Console.WriteLine($"Acquire locak failed due to {resource} after {wait}s timeout.");
}
}
}
}

View file

@ -1,4 +1,3 @@
using BotSharp.Abstraction.Repositories;
using Microsoft.Data.SqlClient;
using MySqlConnector;
using System.Data.Common;

View file

@ -2,10 +2,10 @@ namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver
{
public async Task<string> GetAttributeValue(MessageInfo message, ElementLocatingArgs location, BrowserActionResult result)
public async Task<BrowserActionResult> GetAttributeValue(MessageInfo message, ElementLocatingArgs location)
{
var page = _instance.GetPage(message.ContextId);
ILocator locator = page.Locator(result.Selector);
ILocator locator = page.Locator(location.Selector);
var value = string.Empty;
if (!string.IsNullOrEmpty(location?.AttributeName))
@ -13,6 +13,10 @@ public partial class PlaywrightWebDriver
value = await locator.GetAttributeAsync(location.AttributeName);
}
return value ?? string.Empty;
return new BrowserActionResult
{
IsSuccess = true,
Body = value ?? string.Empty
};
}
}

View file

@ -2,10 +2,10 @@ namespace BotSharp.Plugin.WebDriver.Drivers.SeleniumDriver;
public partial class SeleniumWebDriver
{
public async Task<string> GetAttributeValue(MessageInfo message, ElementLocatingArgs location, BrowserActionResult result)
public async Task<BrowserActionResult> GetAttributeValue(MessageInfo message, ElementLocatingArgs location)
{
var driver = await _instance.InitInstance(message.ContextId);
var locator = driver.FindElement(By.CssSelector(result.Selector));
var locator = driver.FindElement(By.CssSelector(location.Selector));
var value = string.Empty;
if (!string.IsNullOrEmpty(location?.AttributeName))
@ -13,6 +13,10 @@ public partial class SeleniumWebDriver
value = locator.GetAttribute(location.AttributeName);
}
return value ?? string.Empty;
return new BrowserActionResult
{
IsSuccess = true,
Body = value ?? string.Empty
};
}
}