* merged results branch with master
This commit is contained in:
@@ -0,0 +1,8 @@
|
|||||||
|
// This file is used by Code Analysis to maintain SuppressMessage
|
||||||
|
// attributes that are applied to this project.
|
||||||
|
// Project-level suppressions either have no target or are given
|
||||||
|
// a specific target and scoped to a namespace, type, member, etc.
|
||||||
|
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
[assembly: SuppressMessage("Style", "IDE0090")]
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// This file is used by Code Analysis to maintain SuppressMessage
|
||||||
|
// attributes that are applied to this project.
|
||||||
|
// Project-level suppressions either have no target or are given
|
||||||
|
// a specific target and scoped to a namespace, type, member, etc.
|
||||||
|
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
[assembly: SuppressMessage("Style", "IDE0090")]
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Microsoft.Extensions.Primitives;
|
using Microsoft.Extensions.Primitives;
|
||||||
@@ -22,7 +21,7 @@ namespace Telegrator.Hosting.Web.Polling
|
|||||||
private readonly ITelegramBotWebHost _botHost;
|
private readonly ITelegramBotWebHost _botHost;
|
||||||
private readonly ITelegramBotClient _botClient;
|
private readonly ITelegramBotClient _botClient;
|
||||||
private readonly IUpdateRouter _updateRouter;
|
private readonly IUpdateRouter _updateRouter;
|
||||||
private readonly TelegramBotWebOptions _options;
|
private readonly TelegratorWebOptions _options;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initiallizes new instance of <see cref="HostedUpdateWebhooker"/>
|
/// Initiallizes new instance of <see cref="HostedUpdateWebhooker"/>
|
||||||
@@ -32,7 +31,7 @@ namespace Telegrator.Hosting.Web.Polling
|
|||||||
/// <param name="updateRouter"></param>
|
/// <param name="updateRouter"></param>
|
||||||
/// <param name="options"></param>
|
/// <param name="options"></param>
|
||||||
/// <exception cref="ArgumentNullException"></exception>
|
/// <exception cref="ArgumentNullException"></exception>
|
||||||
public HostedUpdateWebhooker(ITelegramBotWebHost botHost, ITelegramBotClient botClient, IUpdateRouter updateRouter, IOptions<TelegramBotWebOptions> options)
|
public HostedUpdateWebhooker(ITelegramBotWebHost botHost, ITelegramBotClient botClient, IUpdateRouter updateRouter, IOptions<TelegratorWebOptions> options)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(options.Value.WebhookUri))
|
if (string.IsNullOrEmpty(options.Value.WebhookUri))
|
||||||
throw new ArgumentNullException(nameof(options), "Option \"WebhookUrl\" must be set to subscribe for update recieving");
|
throw new ArgumentNullException(nameof(options), "Option \"WebhookUrl\" must be set to subscribe for update recieving");
|
||||||
|
|||||||
@@ -43,10 +43,6 @@ namespace Telegrator.Hosting.Web
|
|||||||
_innerBuilder = webApplicationBuilder;
|
_innerBuilder = webApplicationBuilder;
|
||||||
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
|
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
|
||||||
_handlers = new HostHandlersCollection(Services, _settings);
|
_handlers = new HostHandlersCollection(Services, _settings);
|
||||||
|
|
||||||
Services.AddSingleton<IOptions<TelegramBotWebOptions>>(Options.Create(settings));
|
|
||||||
Services.Configure<TelegratorOptions>(Configuration.GetSection(nameof(TelegratorOptions)));
|
|
||||||
Services.Configure<TelegramBotClientOptions>(Configuration.GetSection(nameof(TelegramBotClientOptions)), new TelegramBotClientOptionsProxy());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -67,6 +63,15 @@ namespace Telegrator.Hosting.Web
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_settings.DisableAutoConfigure)
|
||||||
|
{
|
||||||
|
Services.Configure<TelegratorWebOptions>(Configuration.GetSection(nameof(TelegratorWebOptions)));
|
||||||
|
Services.Configure<TelegratorOptions>(Configuration.GetSection(nameof(TelegratorOptions)));
|
||||||
|
Services.Configure<TelegramBotClientOptions>(Configuration.GetSection(nameof(TelegramBotClientOptions)), new TelegramBotClientOptionsProxy());
|
||||||
|
}
|
||||||
|
|
||||||
|
Services.AddSingleton<IConfigurationManager>(Configuration);
|
||||||
|
Services.AddSingleton<IOptions<TelegratorOptions>>(Options.Create(_settings));
|
||||||
return new TelegramBotWebHost(_innerBuilder, _handlers);
|
return new TelegramBotWebHost(_innerBuilder, _handlers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Telegrator.MadiatorCore.Descriptors;
|
|
||||||
using Telegrator.Polling;
|
using Telegrator.Polling;
|
||||||
|
|
||||||
namespace Telegrator.Hosting.Polling
|
namespace Telegrator.Hosting.Polling
|
||||||
@@ -9,12 +8,5 @@ namespace Telegrator.Hosting.Polling
|
|||||||
public class HostUpdateHandlersPool(IOptions<TelegratorOptions> options, ILogger<HostUpdateHandlersPool> logger) : UpdateHandlersPool(options.Value, options.Value.GlobalCancellationToken)
|
public class HostUpdateHandlersPool(IOptions<TelegratorOptions> options, ILogger<HostUpdateHandlersPool> logger) : UpdateHandlersPool(options.Value, options.Value.GlobalCancellationToken)
|
||||||
{
|
{
|
||||||
private readonly ILogger<HostUpdateHandlersPool> _logger = logger;
|
private readonly ILogger<HostUpdateHandlersPool> _logger = logger;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
protected override async Task ExecuteHandlerWrapper(DescribedHandlerInfo enqueuedHandler)
|
|
||||||
{
|
|
||||||
//_logger.LogInformation("Handler \"{0}\" has entered execution pool", enqueuedHandler.DisplayString);
|
|
||||||
await base.ExecuteHandlerWrapper(enqueuedHandler);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ namespace Telegrator.Hosting
|
|||||||
}
|
}
|
||||||
|
|
||||||
Services.AddSingleton<IOptions<TelegratorOptions>>(Options.Create(_settings));
|
Services.AddSingleton<IOptions<TelegratorOptions>>(Options.Create(_settings));
|
||||||
|
Services.AddSingleton<IConfigurationManager>(Configuration);
|
||||||
return new TelegramBotHost(_innerBuilder, _handlers);
|
return new TelegramBotHost(_innerBuilder, _handlers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ namespace Telegrator.Tests
|
|||||||
{
|
{
|
||||||
public bool WasExecuted { get; private set; }
|
public bool WasExecuted { get; private set; }
|
||||||
|
|
||||||
public override Task Execute(IAbstractHandlerContainer<Message> container, CancellationToken cancellationToken)
|
public override Task<Result> Execute(IAbstractHandlerContainer<Message> container, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
WasExecuted = true;
|
WasExecuted = true;
|
||||||
return Task.CompletedTask;
|
return Task.FromResult(Result.Ok());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Telegrator.Analyzers", "Tel
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Telegrator.Hosting.Web", "Telegrator.Hosting.Web\Telegrator.Hosting.Web.csproj", "{98AB490F-6A36-CCFF-F6E6-B029D1665965}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Telegrator.Hosting.Web", "Telegrator.Hosting.Web\Telegrator.Hosting.Web.csproj", "{98AB490F-6A36-CCFF-F6E6-B029D1665965}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SosalBot", "..\SosalBot\SosalBot\SosalBot.csproj", "{D6AA4D47-0DCE-520E-5779-A14EA9CB1DEC}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
AnalyzersDebug|Any CPU = AnalyzersDebug|Any CPU
|
AnalyzersDebug|Any CPU = AnalyzersDebug|Any CPU
|
||||||
@@ -63,6 +65,12 @@ Global
|
|||||||
{98AB490F-6A36-CCFF-F6E6-B029D1665965}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{98AB490F-6A36-CCFF-F6E6-B029D1665965}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{98AB490F-6A36-CCFF-F6E6-B029D1665965}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{98AB490F-6A36-CCFF-F6E6-B029D1665965}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{98AB490F-6A36-CCFF-F6E6-B029D1665965}.Release|Any CPU.Build.0 = Release|Any CPU
|
{98AB490F-6A36-CCFF-F6E6-B029D1665965}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{D6AA4D47-0DCE-520E-5779-A14EA9CB1DEC}.AnalyzersDebug|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{D6AA4D47-0DCE-520E-5779-A14EA9CB1DEC}.AnalyzersDebug|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{D6AA4D47-0DCE-520E-5779-A14EA9CB1DEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{D6AA4D47-0DCE-520E-5779-A14EA9CB1DEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D6AA4D47-0DCE-520E-5779-A14EA9CB1DEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{D6AA4D47-0DCE-520E-5779-A14EA9CB1DEC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -6,11 +6,18 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ITelegratorOptions
|
public interface ITelegratorOptions
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether only the first found handler should be executed for each update.
|
/// Gets or sets a value indicating whether only the first found handler should be executed for each update.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ExecuteOnlyFirstFoundHanlder { get; set; }
|
public bool ExecuteOnlyFirstFoundHanlder { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether to descend the indexr of handler's index on register. ('false' by default)
|
||||||
|
/// </summary>
|
||||||
|
public bool DescendDescriptorIndex { get; set; }
|
||||||
|
*/
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the maximum number of parallel working handlers. Null means no limit.
|
/// Gets or sets the maximum number of parallel working handlers. Null means no limit.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -21,19 +28,14 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ExclusiveAwaitingHandlerRouting { get; set; }
|
public bool ExclusiveAwaitingHandlerRouting { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the global cancellation token for all bot operations.
|
|
||||||
/// </summary>
|
|
||||||
public CancellationToken GlobalCancellationToken { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether to descend the indexr of handler's index on register. ('false' by default)
|
|
||||||
/// </summary>
|
|
||||||
public bool DescendDescriptorIndex { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether to exclude intersecting command aliases.
|
/// Gets or sets a value indicating whether to exclude intersecting command aliases.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ExceptIntersectingCommandAliases { get; set; }
|
public bool ExceptIntersectingCommandAliases { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the global cancellation token for all bot operations.
|
||||||
|
/// </summary>
|
||||||
|
public CancellationToken GlobalCancellationToken { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,10 +51,10 @@ namespace Telegrator.Handlers.Building
|
|||||||
/// <param name="container">The handler container (unused).</param>
|
/// <param name="container">The handler container (unused).</param>
|
||||||
/// <param name="cancellation">The cancellation token (unused).</param>
|
/// <param name="cancellation">The cancellation token (unused).</param>
|
||||||
/// <returns>A completed task.</returns>
|
/// <returns>A completed task.</returns>
|
||||||
protected override Task ExecuteInternal(IHandlerContainer container, CancellationToken cancellation)
|
protected override Task<Result> ExecuteInternal(IHandlerContainer container, CancellationToken cancellation)
|
||||||
{
|
{
|
||||||
ResetEvent.Set();
|
ResetEvent.Set();
|
||||||
return Task.CompletedTask;
|
return Task.FromResult(Result.Ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace Telegrator.Handlers.Building
|
|||||||
/// <param name="container">The handler container with execution context.</param>
|
/// <param name="container">The handler container with execution context.</param>
|
||||||
/// <param name="cancellation">The cancellation token.</param>
|
/// <param name="cancellation">The cancellation token.</param>
|
||||||
/// <returns>A task representing the asynchronous execution.</returns>
|
/// <returns>A task representing the asynchronous execution.</returns>
|
||||||
public override Task Execute(IAbstractHandlerContainer<TUpdate> container, CancellationToken cancellation)
|
public override Task<Result> Execute(IAbstractHandlerContainer<TUpdate> container, CancellationToken cancellation)
|
||||||
=> HandlerAction.Invoke(container, cancellation);
|
=> HandlerAction.Invoke(container, cancellation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace Telegrator.Handlers.Building
|
|||||||
/// <param name="container">The handler container with execution context.</param>
|
/// <param name="container">The handler container with execution context.</param>
|
||||||
/// <param name="cancellation">The cancellation token.</param>
|
/// <param name="cancellation">The cancellation token.</param>
|
||||||
/// <returns>A task representing the asynchronous execution.</returns>
|
/// <returns>A task representing the asynchronous execution.</returns>
|
||||||
public delegate Task AbstractHandlerAction<TUpdate>(IAbstractHandlerContainer<TUpdate> container, CancellationToken cancellation) where TUpdate : class;
|
public delegate Task<Result> AbstractHandlerAction<TUpdate>(IAbstractHandlerContainer<TUpdate> container, CancellationToken cancellation) where TUpdate : class;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Builder class for creating regular handlers that can process updates.
|
/// Builder class for creating regular handlers that can process updates.
|
||||||
|
|||||||
@@ -74,10 +74,10 @@ namespace Telegrator.Handlers.Components
|
|||||||
/// <param name="container">The handler container.</param>
|
/// <param name="container">The handler container.</param>
|
||||||
/// <param name="cancellationToken">Cancellation token.</param>
|
/// <param name="cancellationToken">Cancellation token.</param>
|
||||||
/// <returns>A task representing the asynchronous operation.</returns>
|
/// <returns>A task representing the asynchronous operation.</returns>
|
||||||
protected override sealed async Task ExecuteInternal(IHandlerContainer container, CancellationToken cancellationToken)
|
protected override sealed async Task<Result> ExecuteInternal(IHandlerContainer container, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
Container = (IAbstractHandlerContainer<TUpdate>)container;
|
Container = (IAbstractHandlerContainer<TUpdate>)container;
|
||||||
await Execute(Container, cancellationToken);
|
return await Execute(Container, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -86,6 +86,6 @@ namespace Telegrator.Handlers.Components
|
|||||||
/// <param name="container">The handler container.</param>
|
/// <param name="container">The handler container.</param>
|
||||||
/// <param name="cancellation">Cancellation token.</param>
|
/// <param name="cancellation">Cancellation token.</param>
|
||||||
/// <returns>A task representing the asynchronous operation.</returns>
|
/// <returns>A task representing the asynchronous operation.</returns>
|
||||||
public abstract Task Execute(IAbstractHandlerContainer<TUpdate> container, CancellationToken cancellation);
|
public abstract Task<Result> Execute(IAbstractHandlerContainer<TUpdate> container, CancellationToken cancellation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,13 +118,13 @@ namespace Telegrator.Handlers.Components
|
|||||||
/// <param name="container">The handler container.</param>
|
/// <param name="container">The handler container.</param>
|
||||||
/// <param name="cancellation">The cancellation token.</param>
|
/// <param name="cancellation">The cancellation token.</param>
|
||||||
/// <exception cref="Exception">Thrown when no branch method is set.</exception>
|
/// <exception cref="Exception">Thrown when no branch method is set.</exception>
|
||||||
public override async Task Execute(IAbstractHandlerContainer<TUpdate> container, CancellationToken cancellation)
|
public override async Task<Result> Execute(IAbstractHandlerContainer<TUpdate> container, CancellationToken cancellation)
|
||||||
{
|
{
|
||||||
if (branchMethodInfo is null)
|
if (branchMethodInfo is null)
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
|
|
||||||
Cancellation = cancellation;
|
Cancellation = cancellation;
|
||||||
await BranchExecuteWrapper(container, branchMethodInfo);
|
return await BranchExecuteWrapper(container, branchMethodInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -132,21 +132,20 @@ namespace Telegrator.Handlers.Components
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="container">The handler container.</param>
|
/// <param name="container">The handler container.</param>
|
||||||
/// <param name="methodInfo">The method to execute.</param>
|
/// <param name="methodInfo">The method to execute.</param>
|
||||||
protected virtual async Task BranchExecuteWrapper(IAbstractHandlerContainer<TUpdate> container, MethodInfo methodInfo)
|
protected virtual async Task<Result> BranchExecuteWrapper(IAbstractHandlerContainer<TUpdate> container, MethodInfo methodInfo)
|
||||||
{
|
{
|
||||||
if (methodInfo.ReturnType == typeof(void))
|
if (methodInfo.ReturnType == typeof(void))
|
||||||
{
|
{
|
||||||
methodInfo.Invoke(this, []);
|
methodInfo.Invoke(this, []);
|
||||||
return;
|
return Result.Ok();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
object branchReturn = methodInfo.Invoke(this, []);
|
object branchReturn = methodInfo.Invoke(this, []);
|
||||||
if (branchReturn == null)
|
if (branchReturn is not Task<Result> branchTask)
|
||||||
return;
|
throw new InvalidOperationException();
|
||||||
|
|
||||||
if (branchReturn is Task branchTask)
|
return await branchTask;
|
||||||
await branchTask;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,11 +24,17 @@ namespace Telegrator.Handlers.Components
|
|||||||
/// <param name="container">The <see cref="IHandlerContainer"/> for the update.</param>
|
/// <param name="container">The <see cref="IHandlerContainer"/> for the update.</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||||
public async Task Execute(IHandlerContainer container, CancellationToken cancellationToken = default)
|
public async Task<Result> Execute(IHandlerContainer container, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await ExecuteInternal(container, cancellationToken);
|
||||||
|
}
|
||||||
|
finally
|
||||||
{
|
{
|
||||||
await ExecuteInternal(container, cancellationToken);
|
|
||||||
LifetimeToken.LifetimeEnded();
|
LifetimeToken.LifetimeEnded();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Executes the handler logic for the given container and cancellation token.
|
/// Executes the handler logic for the given container and cancellation token.
|
||||||
@@ -36,6 +42,6 @@ namespace Telegrator.Handlers.Components
|
|||||||
/// <param name="container">The <see cref="IHandlerContainer"/> for the update.</param>
|
/// <param name="container">The <see cref="IHandlerContainer"/> for the update.</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||||
protected abstract Task ExecuteInternal(IHandlerContainer container, CancellationToken cancellationToken);
|
protected abstract Task<Result> ExecuteInternal(IHandlerContainer container, CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
namespace Telegrator.Handlers
|
||||||
|
{
|
||||||
|
public sealed class Result
|
||||||
|
{
|
||||||
|
public bool Positive { get; }
|
||||||
|
|
||||||
|
public bool RouteNext { get; }
|
||||||
|
|
||||||
|
public Type? NextType { get; }
|
||||||
|
|
||||||
|
internal Result(bool positive, bool routeNext, Type? nextType)
|
||||||
|
{
|
||||||
|
Positive = positive;
|
||||||
|
RouteNext = routeNext;
|
||||||
|
NextType = nextType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result Ok()
|
||||||
|
=> new Result(true, false, null);
|
||||||
|
|
||||||
|
public static Result Fault()
|
||||||
|
=> new Result(false, false, null);
|
||||||
|
|
||||||
|
public static Result Next()
|
||||||
|
=> new Result(true, true, null);
|
||||||
|
|
||||||
|
public static Result Next<T>()
|
||||||
|
=> new Result(true, true, typeof(T));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,6 +15,8 @@ namespace Telegrator.MadiatorCore.Descriptors
|
|||||||
/// <typeparam name="TUpdate"></typeparam>
|
/// <typeparam name="TUpdate"></typeparam>
|
||||||
public class MethodHandlerDescriptor<TUpdate> : HandlerDescriptor where TUpdate : class
|
public class MethodHandlerDescriptor<TUpdate> : HandlerDescriptor where TUpdate : class
|
||||||
{
|
{
|
||||||
|
private readonly MethodInfo Method;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes new instance of <see cref="MethodHandlerDescriptor{TUpdate}"/>
|
/// Initializes new instance of <see cref="MethodHandlerDescriptor{TUpdate}"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -28,15 +30,23 @@ namespace Telegrator.MadiatorCore.Descriptors
|
|||||||
UpdateType = handlerAttribute.Type;
|
UpdateType = handlerAttribute.Type;
|
||||||
Indexer = handlerAttribute.GetIndexer();
|
Indexer = handlerAttribute.GetIndexer();
|
||||||
Filters = new DescriptorFiltersSet(handlerAttribute, stateKeeperAttribute, filters);
|
Filters = new DescriptorFiltersSet(handlerAttribute, stateKeeperAttribute, filters);
|
||||||
DisplayString = HandlerInspector.GetDisplayName(action.Method);
|
DisplayString = HandlerInspector.GetDisplayName(action.Method) ?? action.Method.Name;
|
||||||
InstanceFactory = () => new MethodHandler(action.Method, UpdateType);
|
Method = action.Method;
|
||||||
|
InstanceFactory = () => new MethodHandler(UpdateType);
|
||||||
|
LazyInitialization = handler =>
|
||||||
|
{
|
||||||
|
if (handler is not MethodHandler methodHandler)
|
||||||
|
throw new InvalidDataException();
|
||||||
|
|
||||||
|
methodHandler.Method = Method;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private class MethodHandler(MethodInfo method, UpdateType updateType) : AbstractUpdateHandler<TUpdate>(updateType)
|
private class MethodHandler(UpdateType updateType) : AbstractUpdateHandler<TUpdate>(updateType)
|
||||||
{
|
{
|
||||||
private readonly MethodInfo Method = method;
|
internal MethodInfo Method = null!;
|
||||||
|
|
||||||
public override async Task Execute(IAbstractHandlerContainer<TUpdate> container, CancellationToken cancellation)
|
public override async Task<Result> Execute(IAbstractHandlerContainer<TUpdate> container, CancellationToken cancellation)
|
||||||
{
|
{
|
||||||
if (Method is null)
|
if (Method is null)
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
@@ -44,16 +54,15 @@ namespace Telegrator.MadiatorCore.Descriptors
|
|||||||
if (Method.ReturnType == typeof(void))
|
if (Method.ReturnType == typeof(void))
|
||||||
{
|
{
|
||||||
Method.Invoke(this, [container, cancellation]);
|
Method.Invoke(this, [container, cancellation]);
|
||||||
return;
|
return Result.Ok();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
object branchReturn = Method.Invoke(this, [container, cancellation]);
|
object branchReturn = Method.Invoke(this, [container, cancellation]);
|
||||||
if (branchReturn == null)
|
if (branchReturn is not Task<Result> branchTask)
|
||||||
return;
|
throw new InvalidOperationException();
|
||||||
|
|
||||||
if (branchReturn is Task branchTask)
|
return await branchTask;
|
||||||
await branchTask;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using Telegram.Bot.Polling;
|
using Telegram.Bot.Polling;
|
||||||
using Telegram.Bot.Types;
|
using Telegram.Bot.Types;
|
||||||
using Telegrator.Filters.Components;
|
using Telegrator.Filters.Components;
|
||||||
|
using Telegrator.Handlers;
|
||||||
using Telegrator.Handlers.Components;
|
using Telegrator.Handlers.Components;
|
||||||
|
|
||||||
namespace Telegrator.MadiatorCore.Descriptors
|
namespace Telegrator.MadiatorCore.Descriptors
|
||||||
@@ -81,36 +82,43 @@ namespace Telegrator.MadiatorCore.Descriptors
|
|||||||
/// <param name="cancellationToken">Cancellation token.</param>
|
/// <param name="cancellationToken">Cancellation token.</param>
|
||||||
/// <returns>A task representing the asynchronous operation.</returns>
|
/// <returns>A task representing the asynchronous operation.</returns>
|
||||||
/// <exception cref="Exception">Thrown if the handler lifetime has ended or the handler is not a container factory.</exception>
|
/// <exception cref="Exception">Thrown if the handler lifetime has ended or the handler is not a container factory.</exception>
|
||||||
public async Task Execute(CancellationToken cancellationToken)
|
public async Task<Result> Execute(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (HandlerLifetime.IsEnded)
|
if (HandlerLifetime.IsEnded)
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
|
|
||||||
IHandlerContainerFactory? containerFactory = HandlerInstance is IHandlerContainerFactory handlerDefainedContainerFactory
|
|
||||||
? handlerDefainedContainerFactory
|
|
||||||
: UpdateRouter.DefaultContainerFactory is not null
|
|
||||||
? UpdateRouter.DefaultContainerFactory
|
|
||||||
: throw new Exception();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
HandlerContainer = containerFactory.CreateContainer(UpdateRouter.AwaitingProvider, this);
|
HandlerContainer = GetContainer(UpdateRouter.AwaitingProvider, this);
|
||||||
await HandlerInstance.Execute(HandlerContainer, cancellationToken);
|
return await HandlerInstance.Execute(HandlerContainer, cancellationToken);
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
// Cancelled
|
// Cancelled
|
||||||
_ = 0xBAD + 0xC0DE;
|
_ = 0xBAD + 0xC0DE;
|
||||||
return;
|
return Result.Ok();
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
await UpdateRouter
|
await UpdateRouter
|
||||||
.HandleErrorAsync(Client, exception, HandleErrorSource.HandleUpdateError, cancellationToken)
|
.HandleErrorAsync(Client, exception, HandleErrorSource.HandleUpdateError, cancellationToken)
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
return Result.Fault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IHandlerContainer GetContainer(IAwaitingProvider awaitingProvider, DescribedHandlerInfo handlerInfo)
|
||||||
|
{
|
||||||
|
if (HandlerInstance is IHandlerContainerFactory handlerDefainedContainerFactory)
|
||||||
|
return handlerDefainedContainerFactory.CreateContainer(awaitingProvider, handlerInfo);
|
||||||
|
|
||||||
|
if (UpdateRouter.DefaultContainerFactory is not null)
|
||||||
|
return UpdateRouter.DefaultContainerFactory.CreateContainer(awaitingProvider, handlerInfo);
|
||||||
|
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
=> DisplayString ?? HandlerInstance.GetType().Name;
|
=> DisplayString ?? HandlerInstance.GetType().Name;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ namespace Telegrator.MadiatorCore
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="args">The <see cref="DescribedHandlerInfo"/> for the enqueued handler.</param>
|
/// <param name="args">The <see cref="DescribedHandlerInfo"/> for the enqueued handler.</param>
|
||||||
public delegate void HandlerEnqueued(DescribedHandlerInfo args);
|
public delegate void HandlerEnqueued(DescribedHandlerInfo args);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a delegate for when a handler is executing.
|
/// Represents a delegate for when a handler is executing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -24,7 +25,7 @@ namespace Telegrator.MadiatorCore
|
|||||||
public event HandlerEnqueued? HandlerEnqueued;
|
public event HandlerEnqueued? HandlerEnqueued;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when a handler is executing.
|
/// Occurs when a handler is entering execution.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event HandlerExecuting? HandlerExecuting;
|
public event HandlerExecuting? HandlerExecuting;
|
||||||
|
|
||||||
@@ -32,8 +33,9 @@ namespace Telegrator.MadiatorCore
|
|||||||
/// Enqueues a collection of handlers for execution.
|
/// Enqueues a collection of handlers for execution.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="handlers">The handlers to enqueue.</param>
|
/// <param name="handlers">The handlers to enqueue.</param>
|
||||||
public void Enqueue(IEnumerable<DescribedHandlerInfo> handlers);
|
public Task Enqueue(IEnumerable<DescribedHandlerInfo> handlers);
|
||||||
|
|
||||||
|
/*
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enqueues a single handler for execution.
|
/// Enqueues a single handler for execution.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -45,5 +47,6 @@ namespace Telegrator.MadiatorCore
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="token">The <see cref="HandlerLifetimeToken"/> of the handler to dequeue.</param>
|
/// <param name="token">The <see cref="HandlerLifetimeToken"/> of the handler to dequeue.</param>
|
||||||
public void Dequeue(HandlerLifetimeToken token);
|
public void Dequeue(HandlerLifetimeToken token);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
|
namespace Telegrator.Polling
|
||||||
|
{
|
||||||
|
public class LimitedDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDisposable
|
||||||
|
{
|
||||||
|
private readonly int? _maximum;
|
||||||
|
private readonly SemaphoreSlim _semaphore = null!;
|
||||||
|
private readonly ConcurrentDictionary<TKey, TValue> _dict = [];
|
||||||
|
|
||||||
|
public LimitedDictionary(int? maximum)
|
||||||
|
{
|
||||||
|
_maximum = maximum;
|
||||||
|
if (maximum != null)
|
||||||
|
{
|
||||||
|
int value = maximum.Value;
|
||||||
|
_semaphore = new SemaphoreSlim(value, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> Add(TKey key, TValue value, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (_semaphore != null)
|
||||||
|
await _semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
return _dict.TryAdd(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Remove(TKey key, out TValue result)
|
||||||
|
{
|
||||||
|
if (_dict.TryRemove(key, out result))
|
||||||
|
{
|
||||||
|
_semaphore?.Release(1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() => _dict.GetEnumerator();
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() => _dict.GetEnumerator();
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
_semaphore.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
|
namespace Telegrator.Polling
|
||||||
|
{
|
||||||
|
public class LimitedQueue<T>
|
||||||
|
{
|
||||||
|
private readonly int? _maximum;
|
||||||
|
private readonly ConcurrentQueue<T> _queue = [];
|
||||||
|
private readonly SemaphoreSlim _semaphore = null!;
|
||||||
|
|
||||||
|
public LimitedQueue(int? maximum)
|
||||||
|
{
|
||||||
|
_maximum = maximum;
|
||||||
|
if (maximum != null)
|
||||||
|
{
|
||||||
|
int value = maximum.Value;
|
||||||
|
_semaphore = new SemaphoreSlim(value, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Enqueue(T item, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (_maximum.HasValue)
|
||||||
|
await _semaphore.WaitAsync(cancellationToken);
|
||||||
|
|
||||||
|
_queue.Enqueue(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Dequeue(out T result)
|
||||||
|
{
|
||||||
|
if (_queue.TryDequeue(out result))
|
||||||
|
{
|
||||||
|
if (_maximum.HasValue)
|
||||||
|
_semaphore?.Release(1);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using Telegrator.Handlers;
|
||||||
using Telegrator.MadiatorCore;
|
using Telegrator.MadiatorCore;
|
||||||
using Telegrator.MadiatorCore.Descriptors;
|
using Telegrator.MadiatorCore.Descriptors;
|
||||||
|
|
||||||
@@ -15,6 +16,7 @@ namespace Telegrator.Polling
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected object SyncObj = new object();
|
protected object SyncObj = new object();
|
||||||
|
|
||||||
|
/*
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event that signals when awaiting handlers are queued.
|
/// Event that signals when awaiting handlers are queued.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -34,6 +36,13 @@ namespace Telegrator.Polling
|
|||||||
/// Dictionary for tracking currently executing handlers.
|
/// Dictionary for tracking currently executing handlers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected readonly ConcurrentDictionary<HandlerLifetimeToken, Task> ExecutingHandlersPool = [];
|
protected readonly ConcurrentDictionary<HandlerLifetimeToken, Task> ExecutingHandlersPool = [];
|
||||||
|
*/
|
||||||
|
|
||||||
|
//protected readonly ConcurrentDictionary<Type, LimitedQueue<DescribedHandlerInfo>> AwaitingHandlersQueue;
|
||||||
|
|
||||||
|
//protected readonly LimitedDictionary<HandlerLifetimeToken, Task> ExecutingHandlersPool;
|
||||||
|
|
||||||
|
protected SemaphoreSlim ExecutingHandlersSemaphore = null!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The bot configuration options.
|
/// The bot configuration options.
|
||||||
@@ -65,26 +74,62 @@ namespace Telegrator.Polling
|
|||||||
{
|
{
|
||||||
Options = options;
|
Options = options;
|
||||||
GlobalCancellationToken = globalCancellationToken;
|
GlobalCancellationToken = globalCancellationToken;
|
||||||
|
//AwaitingHandlersQueue = new ConcurrentDictionary<Type, LimitedQueue<DescribedHandlerInfo>>();
|
||||||
|
//ExecutingHandlersPool = new LimitedDictionary<HandlerLifetimeToken, Task>(options.MaximumParallelWorkingHandlers);
|
||||||
|
|
||||||
if (options.MaximumParallelWorkingHandlers != null)
|
if (options.MaximumParallelWorkingHandlers != null)
|
||||||
{
|
{
|
||||||
ExecutingHandlersSemaphore = new SemaphoreSlim(options.MaximumParallelWorkingHandlers ?? 0);
|
ExecutingHandlersSemaphore = new SemaphoreSlim(options.MaximumParallelWorkingHandlers.Value);
|
||||||
AwaitingHandlersQueuedEvent = new ManualResetEventSlim(false);
|
//AwaitingHandlersQueuedEvent = new ManualResetEventSlim(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if (Options.MaximumParallelWorkingHandlers != null)
|
if (Options.MaximumParallelWorkingHandlers != null)
|
||||||
HandlersCheckpoint();
|
HandlersCheckpoint();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void Enqueue(IEnumerable<DescribedHandlerInfo> handlers)
|
public async Task Enqueue(IEnumerable<DescribedHandlerInfo> handlers)
|
||||||
{
|
{
|
||||||
handlers.ForEach(Enqueue);
|
//handlers.ForEach(Enqueue);
|
||||||
|
|
||||||
|
Result? lastResult = null;
|
||||||
|
foreach (DescribedHandlerInfo handlerInfo in handlers)
|
||||||
|
{
|
||||||
|
if (lastResult?.NextType != null)
|
||||||
|
{
|
||||||
|
if (lastResult.NextType != handlerInfo.HandlerInstance.GetType())
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ExecutingHandlersSemaphore != null)
|
||||||
|
{
|
||||||
|
await ExecutingHandlersSemaphore.WaitAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HandlerExecuting?.Invoke(handlerInfo);
|
||||||
|
lastResult = await handlerInfo.Execute(GlobalCancellationToken);
|
||||||
|
ExecutingHandlersSemaphore?.Release(1);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lastResult.RouteNext)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void Enqueue(DescribedHandlerInfo handlerInfo)
|
public void Enqueue(DescribedHandlerInfo handlerInfo)
|
||||||
{
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
|
||||||
if (Options.MaximumParallelWorkingHandlers == null)
|
if (Options.MaximumParallelWorkingHandlers == null)
|
||||||
{
|
{
|
||||||
Task.Run(async () => await ExecuteHandlerWrapper(handlerInfo));
|
Task.Run(async () => await ExecuteHandlerWrapper(handlerInfo));
|
||||||
@@ -111,7 +156,9 @@ namespace Telegrator.Polling
|
|||||||
ExecutingHandlersSemaphore.Release(1);
|
ExecutingHandlersSemaphore.Release(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Main checkpoint method that manages handler execution in a loop.
|
/// Main checkpoint method that manages handler execution in a loop.
|
||||||
/// Continuously processes queued handlers while respecting concurrency limits.
|
/// Continuously processes queued handlers while respecting concurrency limits.
|
||||||
@@ -206,6 +253,7 @@ namespace Telegrator.Polling
|
|||||||
return AwaitingHandlersQueue.TryDequeue(out enqueuedHandler);
|
return AwaitingHandlersQueue.TryDequeue(out enqueuedHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Disposes of the handlers pool and releases all resources.
|
/// Disposes of the handlers pool and releases all resources.
|
||||||
@@ -221,11 +269,13 @@ namespace Telegrator.Polling
|
|||||||
ExecutingHandlersSemaphore = null!;
|
ExecutingHandlersSemaphore = null!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if (AwaitingHandlersQueuedEvent != null)
|
if (AwaitingHandlersQueuedEvent != null)
|
||||||
{
|
{
|
||||||
AwaitingHandlersQueuedEvent.Dispose();
|
AwaitingHandlersQueuedEvent.Dispose();
|
||||||
AwaitingHandlersQueuedEvent = null!;
|
AwaitingHandlersQueuedEvent = null!;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if (SyncObj != null)
|
if (SyncObj != null)
|
||||||
SyncObj = null!;
|
SyncObj = null!;
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ namespace Telegrator.Polling
|
|||||||
/// <param name="update">The update to handle.</param>
|
/// <param name="update">The update to handle.</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>A task representing the asynchronous update handling operation.</returns>
|
/// <returns>A task representing the asynchronous update handling operation.</returns>
|
||||||
public virtual Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
|
public virtual async Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Logging
|
// Logging
|
||||||
Alligator.RouterWriteLine("Received Update ({0}) of type \"{1}\"", update.Id, update.Type);
|
Alligator.RouterWriteLine("Received Update ({0}) of type \"{1}\"", update.Id, update.Type);
|
||||||
@@ -109,31 +109,28 @@ namespace Telegrator.Polling
|
|||||||
if (handlers.Any())
|
if (handlers.Any())
|
||||||
{
|
{
|
||||||
// Enqueuing found awiting handlers
|
// Enqueuing found awiting handlers
|
||||||
HandlersPool.Enqueue(handlers);
|
await HandlersPool.Enqueue(handlers);
|
||||||
|
|
||||||
// Chicking if awaiting handlers has exclusive routing
|
// Chicking if awaiting handlers has exclusive routing
|
||||||
if (Options.ExclusiveAwaitingHandlerRouting)
|
if (Options.ExclusiveAwaitingHandlerRouting)
|
||||||
{
|
{
|
||||||
Alligator.RouterWriteLine("Receiving Update ({0}) completed with only awaiting handlers", update.Id);
|
Alligator.RouterWriteLine("Receiving Update ({0}) completed with only awaiting handlers", update.Id);
|
||||||
return Task.CompletedTask;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Queuing reagular handlers for execution
|
// Queuing reagular handlers for execution
|
||||||
HandlersPool.Enqueue(GetHandlers(HandlersProvider, this, botClient, update, cancellationToken));
|
await HandlersPool.Enqueue(GetHandlers(HandlersProvider, this, botClient, update, cancellationToken));
|
||||||
Alligator.RouterWriteLine("Receiving Update ({0}) finished", update.Id);
|
Alligator.RouterWriteLine("Receiving Update ({0}) finished", update.Id);
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
Alligator.RouterWriteLine("Receiving Update ({0}) cancelled", update.Id);
|
Alligator.RouterWriteLine("Receiving Update ({0}) cancelled", update.Id);
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Alligator.RouterWriteLine("Receiving Update ({0}) finished with exception {1}", update.Id, ex.Message);
|
Alligator.RouterWriteLine("Receiving Update ({0}) finished with exception {1}", update.Id, ex.Message);
|
||||||
ExceptionHandler?.HandleException(botClient, ex, HandleErrorSource.PollingError, cancellationToken);
|
ExceptionHandler?.HandleException(botClient, ex, HandleErrorSource.PollingError, cancellationToken);
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,10 +159,11 @@ namespace Telegrator.Polling
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<DescribedHandlerInfo> described = DescribeDescriptors(provider, descriptors, updateRouter, client, update, cancellationToken);
|
//IEnumerable<DescribedHandlerInfo> described = DescribeDescriptors(provider, descriptors, updateRouter, client, update, cancellationToken);
|
||||||
Alligator.RouterWriteLine("Described total of {0} handlers for Update ({1}) from {2} provider", described.Count(), update.Id, provider.GetType().Name);
|
//Alligator.RouterWriteLine("Described total of {0} handlers for Update ({1}) from {2} provider", described.Count(), update.Id, provider.GetType().Name);
|
||||||
Alligator.RouterWriteLine("Described handlers : {0}", string.Join(", ", described));
|
//Alligator.RouterWriteLine("Described handlers : {0}", string.Join(", ", described));
|
||||||
return described;
|
|
||||||
|
return DescribeDescriptors(provider, descriptors, updateRouter, client, update, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -192,8 +190,11 @@ namespace Telegrator.Polling
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
yield return describedHandler;
|
yield return describedHandler;
|
||||||
|
|
||||||
|
/*
|
||||||
if (Options.ExecuteOnlyFirstFoundHanlder)
|
if (Options.ExecuteOnlyFirstFoundHanlder)
|
||||||
break;
|
break;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|||||||
@@ -8,23 +8,24 @@ namespace Telegrator
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class TelegratorOptions : ITelegratorOptions
|
public class TelegratorOptions : ITelegratorOptions
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool ExecuteOnlyFirstFoundHanlder { get; set; }
|
public bool ExecuteOnlyFirstFoundHanlder { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool DescendDescriptorIndex { get; set; } = true;
|
||||||
|
*/
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public int? MaximumParallelWorkingHandlers { get; set; }
|
public int? MaximumParallelWorkingHandlers { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool ExclusiveAwaitingHandlerRouting { get; set; }
|
public bool ExclusiveAwaitingHandlerRouting { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public CancellationToken GlobalCancellationToken { get; set; }
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public bool DescendDescriptorIndex { get; set; } = true;
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool ExceptIntersectingCommandAliases { get; set; } = true;
|
public bool ExceptIntersectingCommandAliases { get; set; } = true;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public CancellationToken GlobalCancellationToken { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user