V13-FE-011: finalize search list layout slice
This commit is contained in:
+46
@@ -0,0 +1,46 @@
|
||||
using Kbx.Shared.Integrations.Generated;
|
||||
|
||||
namespace Kbx.Shared.Integrations;
|
||||
|
||||
public sealed class KbxOutboxIntegrationDispatcher(
|
||||
IKbxIntegrationAdapterRegistry adapters,
|
||||
KbxIntegrationAttemptRepository attempts,
|
||||
KbxPollyIntegrationPipeline pipelineFactory,
|
||||
KbxIntegrationOperationsProjector operations)
|
||||
{
|
||||
public async Task<KbxIntegrationAttemptResult> DispatchAsync(KbxIntegrationMessage message, int durableAttempt, CancellationToken ct)
|
||||
{
|
||||
if (!KbxIntegrationCatalog.All.TryGetValue(message.IntegrationId, out var definition))
|
||||
return new(false, KbxIntegrationFailureKind.Permanent, "INTEGRATION_NOT_REGISTERED", message.IntegrationId);
|
||||
|
||||
var attemptId = await attempts.StartAsync(message, durableAttempt, ct);
|
||||
var pipeline = pipelineFactory.Build(
|
||||
definition.ShortRetryAttempts,
|
||||
TimeSpan.FromMilliseconds(definition.ShortRetryBaseDelayMs),
|
||||
TimeSpan.FromMilliseconds(definition.TimeoutMs),
|
||||
definition.CircuitFailureRatio,
|
||||
TimeSpan.FromSeconds(definition.CircuitSamplingSeconds),
|
||||
definition.CircuitMinimumThroughput,
|
||||
TimeSpan.FromSeconds(definition.CircuitBreakSeconds));
|
||||
|
||||
KbxIntegrationAttemptResult result;
|
||||
try
|
||||
{
|
||||
var adapter = adapters.GetRequired(message.IntegrationId);
|
||||
result = await pipeline.ExecuteAsync(async token => await adapter.SendAsync(message, token), ct);
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
result = new(false, KbxIntegrationFailureClassifier.Classify(error), error.GetType().Name, "외부 연계 호출이 완료되지 않았습니다.");
|
||||
}
|
||||
|
||||
// A transient result is persisted and delegated to Hangfire for durable retry.
|
||||
var state = result.Succeeded ? "delivered" : result.FailureKind == KbxIntegrationFailureKind.Transient ? "retrying" : "failed";
|
||||
var next = state == "retrying" ? KbxDurableIntegrationRetryPlanner.NextAttemptAt(definition, durableAttempt, DateTimeOffset.UtcNow) : null;
|
||||
await attempts.CompleteAsync(attemptId, result, state, next, ct);
|
||||
if (result.Succeeded) await operations.OnDeliveredAsync(message, definition, ct);
|
||||
else if (result.FailureKind == KbxIntegrationFailureKind.Permanent && definition.TerminalAction == "operations-exception")
|
||||
await operations.OnPermanentFailureAsync(message, definition, result, ct);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user