bcquality/custom/knowledge/integration/batch-outbound-work-only-when-the-remote-supports-it.good.al

39 lines
1.7 KiB
AL

// Best practice: send one bounded batch to a remote that returns per-item
// status, carry a per-item idempotency key inside the batch, and settle each
// Integration Message individually from its own result. A partial failure parks
// only the items that actually failed; a retry of the batch is safe because the
// items that already succeeded carry the same keys.
codeunit 50150 "WMS Batch Sender"
{
TableNo = "Job Queue Entry";
trigger OnRun()
var
IntegrationMessage: Record "Integration Message";
BatchBuilder: Codeunit "WMS Batch Builder";
BatchSize: Integer;
begin
// Size is tuned from telemetry, smaller for stages that lock. Not a constant.
BatchSize := GetTunedBatchSize();
IntegrationMessage.SetRange(Direction, IntegrationMessage.Direction::Outbound);
IntegrationMessage.SetRange(Status, IntegrationMessage.Status::New);
IntegrationMessage.SetRange(Type, 'wms-shipment');
if IntegrationMessage.FindSet() then
repeat
// Each item carries its own Message ID as the idempotency key,
// so re-sending the batch never double-processes a sent item.
BatchBuilder.AddItem(IntegrationMessage."Message ID", IntegrationMessage);
until (IntegrationMessage.Next() = 0) or (BatchBuilder.Count() >= BatchSize);
// One call. The remote returns a result per item, keyed by Message ID.
SendBatchAndSettleEachItem(BatchBuilder);
end;
local procedure SendBatchAndSettleEachItem(var BatchBuilder: Codeunit "WMS Batch Builder")
begin
// For each per-item result: set that one message Resolved or Failed.
// A single bad item parks only itself; the rest move on.
end;
}