* Added Result class to communicate with router from handler
* Removed "ExecuteOnlyFirstFoundHanlder" in sake of testing new Result pattern based routing system * Removed obsolete option property "DescendDescriptorIndex" * Changed router logic * Changed handlers pool logic
This commit is contained in:
@@ -6,11 +6,18 @@
|
||||
/// </summary>
|
||||
public interface ITelegratorOptions
|
||||
{
|
||||
/*
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether only the first found handler should be executed for each update.
|
||||
/// </summary>
|
||||
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>
|
||||
/// Gets or sets the maximum number of parallel working handlers. Null means no limit.
|
||||
/// </summary>
|
||||
@@ -21,19 +28,14 @@
|
||||
/// </summary>
|
||||
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>
|
||||
/// Gets or sets a value indicating whether to exclude intersecting command aliases.
|
||||
/// </summary>
|
||||
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="cancellation">The cancellation token (unused).</param>
|
||||
/// <returns>A completed task.</returns>
|
||||
protected override Task ExecuteInternal(IHandlerContainer container, CancellationToken cancellation)
|
||||
protected override Task<Result> ExecuteInternal(IHandlerContainer container, CancellationToken cancellation)
|
||||
{
|
||||
ResetEvent.Set();
|
||||
return Task.CompletedTask;
|
||||
return Task.FromResult(Result.Ok());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Telegrator.Handlers.Building
|
||||
/// <param name="container">The handler container with execution context.</param>
|
||||
/// <param name="cancellation">The cancellation token.</param>
|
||||
/// <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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Telegrator.Handlers.Building
|
||||
/// <param name="container">The handler container with execution context.</param>
|
||||
/// <param name="cancellation">The cancellation token.</param>
|
||||
/// <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>
|
||||
/// 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="cancellationToken">Cancellation token.</param>
|
||||
/// <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;
|
||||
await Execute(Container, cancellationToken);
|
||||
return await Execute(Container, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -86,6 +86,6 @@ namespace Telegrator.Handlers.Components
|
||||
/// <param name="container">The handler container.</param>
|
||||
/// <param name="cancellation">Cancellation token.</param>
|
||||
/// <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="cancellation">The cancellation token.</param>
|
||||
/// <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)
|
||||
throw new Exception();
|
||||
|
||||
Cancellation = cancellation;
|
||||
await BranchExecuteWrapper(container, branchMethodInfo);
|
||||
return await BranchExecuteWrapper(container, branchMethodInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -132,21 +132,20 @@ namespace Telegrator.Handlers.Components
|
||||
/// </summary>
|
||||
/// <param name="container">The handler container.</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))
|
||||
{
|
||||
methodInfo.Invoke(this, []);
|
||||
return;
|
||||
return Result.Ok();
|
||||
}
|
||||
else
|
||||
{
|
||||
object branchReturn = methodInfo.Invoke(this, []);
|
||||
if (branchReturn == null)
|
||||
return;
|
||||
|
||||
if (branchReturn is Task branchTask)
|
||||
await branchTask;
|
||||
if (branchReturn is not Task<Result> branchTask)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
return await branchTask;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,10 +24,16 @@ namespace Telegrator.Handlers.Components
|
||||
/// <param name="container">The <see cref="IHandlerContainer"/> for the update.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <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)
|
||||
{
|
||||
await ExecuteInternal(container, cancellationToken);
|
||||
LifetimeToken.LifetimeEnded();
|
||||
try
|
||||
{
|
||||
return await ExecuteInternal(container, cancellationToken);
|
||||
}
|
||||
finally
|
||||
{
|
||||
LifetimeToken.LifetimeEnded();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -36,6 +42,6 @@ namespace Telegrator.Handlers.Components
|
||||
/// <param name="container">The <see cref="IHandlerContainer"/> for the update.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <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));
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ namespace Telegrator.MadiatorCore.Descriptors
|
||||
{
|
||||
private readonly MethodInfo Method = method;
|
||||
|
||||
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)
|
||||
throw new Exception();
|
||||
@@ -44,16 +44,15 @@ namespace Telegrator.MadiatorCore.Descriptors
|
||||
if (Method.ReturnType == typeof(void))
|
||||
{
|
||||
Method.Invoke(this, [container, cancellation]);
|
||||
return;
|
||||
return Result.Ok();
|
||||
}
|
||||
else
|
||||
{
|
||||
object branchReturn = Method.Invoke(this, [container, cancellation]);
|
||||
if (branchReturn == null)
|
||||
return;
|
||||
if (branchReturn is not Task<Result> branchTask)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
if (branchReturn is Task branchTask)
|
||||
await branchTask;
|
||||
return await branchTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Telegram.Bot.Polling;
|
||||
using Telegram.Bot.Types;
|
||||
using Telegrator.Filters.Components;
|
||||
using Telegrator.Handlers;
|
||||
using Telegrator.Handlers.Components;
|
||||
|
||||
namespace Telegrator.MadiatorCore.Descriptors
|
||||
@@ -81,36 +82,43 @@ namespace Telegrator.MadiatorCore.Descriptors
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <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>
|
||||
public async Task Execute(CancellationToken cancellationToken)
|
||||
public async Task<Result> Execute(CancellationToken cancellationToken)
|
||||
{
|
||||
if (HandlerLifetime.IsEnded)
|
||||
throw new Exception();
|
||||
|
||||
IHandlerContainerFactory? containerFactory = HandlerInstance is IHandlerContainerFactory handlerDefainedContainerFactory
|
||||
? handlerDefainedContainerFactory
|
||||
: UpdateRouter.DefaultContainerFactory is not null
|
||||
? UpdateRouter.DefaultContainerFactory
|
||||
: throw new Exception();
|
||||
|
||||
try
|
||||
{
|
||||
HandlerContainer = containerFactory.CreateContainer(UpdateRouter.AwaitingProvider, this);
|
||||
await HandlerInstance.Execute(HandlerContainer, cancellationToken);
|
||||
HandlerContainer = GetContainer(UpdateRouter.AwaitingProvider, this);
|
||||
return await HandlerInstance.Execute(HandlerContainer, cancellationToken);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// Cancelled
|
||||
_ = 0xBAD + 0xC0DE;
|
||||
return;
|
||||
return Result.Ok();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
await UpdateRouter
|
||||
.HandleErrorAsync(Client, exception, HandleErrorSource.HandleUpdateError, cancellationToken)
|
||||
.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/>
|
||||
public override string ToString()
|
||||
=> DisplayString ?? HandlerInstance.GetType().Name;
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace Telegrator.MadiatorCore
|
||||
/// </summary>
|
||||
/// <param name="args">The <see cref="DescribedHandlerInfo"/> for the enqueued handler.</param>
|
||||
public delegate void HandlerEnqueued(DescribedHandlerInfo args);
|
||||
|
||||
/// <summary>
|
||||
/// Represents a delegate for when a handler is executing.
|
||||
/// </summary>
|
||||
@@ -24,7 +25,7 @@ namespace Telegrator.MadiatorCore
|
||||
public event HandlerEnqueued? HandlerEnqueued;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a handler is executing.
|
||||
/// Occurs when a handler is entering execution.
|
||||
/// </summary>
|
||||
public event HandlerExecuting? HandlerExecuting;
|
||||
|
||||
@@ -32,8 +33,9 @@ namespace Telegrator.MadiatorCore
|
||||
/// Enqueues a collection of handlers for execution.
|
||||
/// </summary>
|
||||
/// <param name="handlers">The handlers to enqueue.</param>
|
||||
public void Enqueue(IEnumerable<DescribedHandlerInfo> handlers);
|
||||
public Task Enqueue(IEnumerable<DescribedHandlerInfo> handlers);
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
/// Enqueues a single handler for execution.
|
||||
/// </summary>
|
||||
@@ -45,5 +47,6 @@ namespace Telegrator.MadiatorCore
|
||||
/// </summary>
|
||||
/// <param name="token">The <see cref="HandlerLifetimeToken"/> of the handler to dequeue.</param>
|
||||
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 Telegrator.Handlers;
|
||||
using Telegrator.MadiatorCore;
|
||||
using Telegrator.MadiatorCore.Descriptors;
|
||||
|
||||
@@ -15,6 +16,7 @@ namespace Telegrator.Polling
|
||||
/// </summary>
|
||||
protected object SyncObj = new object();
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
/// Event that signals when awaiting handlers are queued.
|
||||
/// </summary>
|
||||
@@ -34,6 +36,13 @@ namespace Telegrator.Polling
|
||||
/// Dictionary for tracking currently executing handlers.
|
||||
/// </summary>
|
||||
protected readonly ConcurrentDictionary<HandlerLifetimeToken, Task> ExecutingHandlersPool = [];
|
||||
*/
|
||||
|
||||
//protected readonly ConcurrentDictionary<Type, LimitedQueue<DescribedHandlerInfo>> AwaitingHandlersQueue;
|
||||
|
||||
//protected readonly LimitedDictionary<HandlerLifetimeToken, Task> ExecutingHandlersPool;
|
||||
|
||||
protected SemaphoreSlim ExecutingHandlersSemaphore = null!;
|
||||
|
||||
/// <summary>
|
||||
/// The bot configuration options.
|
||||
@@ -65,26 +74,62 @@ namespace Telegrator.Polling
|
||||
{
|
||||
Options = options;
|
||||
GlobalCancellationToken = globalCancellationToken;
|
||||
//AwaitingHandlersQueue = new ConcurrentDictionary<Type, LimitedQueue<DescribedHandlerInfo>>();
|
||||
//ExecutingHandlersPool = new LimitedDictionary<HandlerLifetimeToken, Task>(options.MaximumParallelWorkingHandlers);
|
||||
|
||||
if (options.MaximumParallelWorkingHandlers != null)
|
||||
{
|
||||
ExecutingHandlersSemaphore = new SemaphoreSlim(options.MaximumParallelWorkingHandlers ?? 0);
|
||||
AwaitingHandlersQueuedEvent = new ManualResetEventSlim(false);
|
||||
ExecutingHandlersSemaphore = new SemaphoreSlim(options.MaximumParallelWorkingHandlers.Value);
|
||||
//AwaitingHandlersQueuedEvent = new ManualResetEventSlim(false);
|
||||
}
|
||||
|
||||
/*
|
||||
if (Options.MaximumParallelWorkingHandlers != null)
|
||||
HandlersCheckpoint();
|
||||
*/
|
||||
}
|
||||
|
||||
/// <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/>
|
||||
public void Enqueue(DescribedHandlerInfo handlerInfo)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
||||
if (Options.MaximumParallelWorkingHandlers == null)
|
||||
{
|
||||
Task.Run(async () => await ExecuteHandlerWrapper(handlerInfo));
|
||||
@@ -111,7 +156,9 @@ namespace Telegrator.Polling
|
||||
ExecutingHandlersSemaphore.Release(1);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
/// Main checkpoint method that manages handler execution in a loop.
|
||||
/// Continuously processes queued handlers while respecting concurrency limits.
|
||||
@@ -206,6 +253,7 @@ namespace Telegrator.Polling
|
||||
return AwaitingHandlersQueue.TryDequeue(out enqueuedHandler);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Disposes of the handlers pool and releases all resources.
|
||||
@@ -221,11 +269,13 @@ namespace Telegrator.Polling
|
||||
ExecutingHandlersSemaphore = null!;
|
||||
}
|
||||
|
||||
/*
|
||||
if (AwaitingHandlersQueuedEvent != null)
|
||||
{
|
||||
AwaitingHandlersQueuedEvent.Dispose();
|
||||
AwaitingHandlersQueuedEvent = null!;
|
||||
}
|
||||
*/
|
||||
|
||||
if (SyncObj != null)
|
||||
SyncObj = null!;
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace Telegrator.Polling
|
||||
/// <param name="update">The update to handle.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <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
|
||||
Alligator.RouterWriteLine("Received Update ({0}) of type \"{1}\"", update.Id, update.Type);
|
||||
@@ -109,31 +109,28 @@ namespace Telegrator.Polling
|
||||
if (handlers.Any())
|
||||
{
|
||||
// Enqueuing found awiting handlers
|
||||
HandlersPool.Enqueue(handlers);
|
||||
await HandlersPool.Enqueue(handlers);
|
||||
|
||||
// Chicking if awaiting handlers has exclusive routing
|
||||
if (Options.ExclusiveAwaitingHandlerRouting)
|
||||
{
|
||||
Alligator.RouterWriteLine("Receiving Update ({0}) completed with only awaiting handlers", update.Id);
|
||||
return Task.CompletedTask;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
Alligator.RouterWriteLine("Receiving Update ({0}) cancelled", update.Id);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Alligator.RouterWriteLine("Receiving Update ({0}) finished with exception {1}", update.Id, ex.Message);
|
||||
ExceptionHandler?.HandleException(botClient, ex, HandleErrorSource.PollingError, cancellationToken);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,10 +159,11 @@ namespace Telegrator.Polling
|
||||
return [];
|
||||
}
|
||||
|
||||
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 handlers : {0}", string.Join(", ", described));
|
||||
return described;
|
||||
//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 handlers : {0}", string.Join(", ", described));
|
||||
|
||||
return DescribeDescriptors(provider, descriptors, updateRouter, client, update, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -192,8 +190,11 @@ namespace Telegrator.Polling
|
||||
continue;
|
||||
|
||||
yield return describedHandler;
|
||||
|
||||
/*
|
||||
if (Options.ExecuteOnlyFirstFoundHanlder)
|
||||
break;
|
||||
*/
|
||||
}
|
||||
}
|
||||
finally
|
||||
|
||||
@@ -8,23 +8,24 @@ namespace Telegrator
|
||||
/// </summary>
|
||||
public class TelegratorOptions : ITelegratorOptions
|
||||
{
|
||||
/*
|
||||
/// <inheritdoc/>
|
||||
public bool ExecuteOnlyFirstFoundHanlder { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool DescendDescriptorIndex { get; set; } = true;
|
||||
*/
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int? MaximumParallelWorkingHandlers { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool ExclusiveAwaitingHandlerRouting { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public CancellationToken GlobalCancellationToken { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool DescendDescriptorIndex { get; set; } = true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool ExceptIntersectingCommandAliases { get; set; } = true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public CancellationToken GlobalCancellationToken { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user