подписка
This commit is contained in:
+18
-1
@@ -5,6 +5,7 @@ using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Tnsu.ApprovalRoute.Infrastructure.Persistence;
|
||||
using Tnsu.ApprovalRoute.Infrastructure.SharePoint;
|
||||
using Tnsu.ApprovalRoute.Infrastructure.TnsuPortal;
|
||||
|
||||
namespace Tnsu.ApprovalRoute.Application.ListPartitioning;
|
||||
|
||||
@@ -35,11 +36,27 @@ public sealed class CreateNextListPartitionJob(
|
||||
ListPartitioningLock provisioningLock,
|
||||
ListPartitionRegistry registry,
|
||||
ISharePointListProvisioner provisioner,
|
||||
TnsuPortalCallerToken callerToken,
|
||||
IOptions<ListPartitioningOptions> options,
|
||||
ILogger<CreateNextListPartitionJob> logger)
|
||||
{
|
||||
public async Task RunAsync(int requestTypeId, CancellationToken cancellationToken)
|
||||
/// <param name="authorization">
|
||||
/// Заголовок Authorization пользователя, чей запрос вызвал провижининг (см.
|
||||
/// ListPartitionService.TryEnqueueProvisioningAsync). Нужен, чтобы подписать
|
||||
/// новый список на уведомления от имени этого пользователя: своего HttpContext
|
||||
/// у фоновой задачи нет, а client_credentials сейчас не настроен (см.
|
||||
/// TnsuPortalAuthorizer). Провижининг занимает секунды, поэтому токен не
|
||||
/// успевает истечь — но на ПОВТОРЕ Hangfire (минуты спустя) он уже может быть
|
||||
/// просроченным: тогда подписка вернёт 401 и упадёт мягко, не сорвав создание
|
||||
/// списка (см. ISharePointWebhookSubscriber).
|
||||
///
|
||||
/// Учтите: как аргумент задачи он попадает в хранилище Hangfire (Postgres) и
|
||||
/// виден в его дашборде.
|
||||
/// </param>
|
||||
public async Task RunAsync(int requestTypeId, string? authorization, CancellationToken cancellationToken)
|
||||
{
|
||||
callerToken.Set(authorization);
|
||||
|
||||
// Единственная настоящая защита от параллельного запуска: атомарный захват
|
||||
// флага в строке request_types. Проверка перед постановкой в очередь —
|
||||
// только чтобы не плодить лишние задачи; гонку разруливает именно здесь.
|
||||
|
||||
@@ -7,6 +7,7 @@ using Tnsu.ApprovalRoute.Application.Common.Errors;
|
||||
using Tnsu.ApprovalRoute.Domain.Entities;
|
||||
using Tnsu.ApprovalRoute.Infrastructure.Persistence;
|
||||
using Tnsu.ApprovalRoute.Infrastructure.SharePoint;
|
||||
using Tnsu.ApprovalRoute.Infrastructure.TnsuPortal;
|
||||
|
||||
namespace Tnsu.ApprovalRoute.Application.ListPartitioning;
|
||||
|
||||
@@ -19,6 +20,7 @@ public sealed class ListPartitionService(
|
||||
ISharePointClient sharePoint,
|
||||
ListPartitionRegistry registry,
|
||||
IBackgroundJobClient backgroundJobs,
|
||||
TnsuPortalCallerToken callerToken,
|
||||
IOptions<ListPartitioningOptions> options,
|
||||
ILogger<ListPartitionService> logger)
|
||||
{
|
||||
@@ -151,8 +153,12 @@ public sealed class ListPartitionService(
|
||||
// самой задачи (см. CreateNextListPartitionJob).
|
||||
if (requestType.ListPartitioningStartedAt is not null) return false;
|
||||
|
||||
// Токен ЭТОГО запроса уезжает в задачу: подписать новый список на
|
||||
// уведомления нужно от имени пользователя, а своего токена у фоновой задачи
|
||||
// нет (см. CreateNextListPartitionJob.RunAsync — там же про его хранение и
|
||||
// срок жизни).
|
||||
backgroundJobs.Enqueue<CreateNextListPartitionJob>(
|
||||
job => job.RunAsync(requestType.Id, CancellationToken.None));
|
||||
job => job.RunAsync(requestType.Id, callerToken.Current, CancellationToken.None));
|
||||
|
||||
logger.LogInformation(
|
||||
"В списке {ListId} типа заявок {RequestTypeId} {ItemCount} элементов (порог {Threshold}) — " +
|
||||
|
||||
Reference in New Issue
Block a user