DistributedLocker
This commit is contained in:
parent
5604273d1d
commit
1cfa6a8618
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
using BotSharp.Abstraction.Repositories;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using MySqlConnector;
|
||||
using System.Data.Common;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue