43 lines
2.0 KiB
C#
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);
|
|
}
|
|
}
|