Files
KArtSell.Aegis/docs/Design/kbx-foundation-v36/backend/Shared/Integrations/KbxIntegrationRetryActionHandler.cs
T

43 lines
2.0 KiB
C#

using Dapper;
using Npgsql;
using Shared.Operations;
namespace Kbx.Shared.Integrations;
public sealed class KbxIntegrationRetryActionHandler(NpgsqlDataSource dataSource) : IWorkItemActionHandler
{
public string Key => "integration.retry";
public async Task ExecuteAsync(string tenantId, string actorId, Guid workItemId, CancellationToken ct)
{
await using var connection = await dataSource.OpenConnectionAsync(ct);
await using var tx = await connection.BeginTransactionAsync(ct);
var messageId = await connection.QuerySingleOrDefaultAsync<Guid?>(new CommandDefinition("""
select source_id::uuid
from kbx.work_items
where id=@WorkItemId and tenant_id=@TenantId and retry_action_key='integration.retry'
for update;
""", new { WorkItemId = workItemId, TenantId = tenantId }, tx, cancellationToken: ct));
if (messageId is null) { await tx.RollbackAsync(ct); return; }
var changed = await connection.ExecuteAsync(new CommandDefinition("""
update kbx.integration_attempts
set state='retrying', next_retry_at=now()
where id = (
select id from kbx.integration_attempts
where message_id=@MessageId and state='failed'
order by attempt_no desc limit 1
);
""", new { MessageId = messageId.Value }, tx, cancellationToken: ct));
if (changed == 1)
{
await connection.ExecuteAsync(new CommandDefinition("""
insert into kbx.work_item_audit(id,work_item_id,tenant_id,action,actor_id,actor_name,reason,before_status,after_status)
values(gen_random_uuid(),@WorkItemId,@TenantId,'integration-retry',@ActorId,@ActorId,'안전한 연계 재처리 예약','open','open');
""", new { WorkItemId = workItemId, TenantId = tenantId, ActorId = actorId }, tx, cancellationToken: ct));
}
await tx.CommitAsync(ct);
}
}