deliver method
Delivers a CEP trigger into the Digia engine.
A total function: it never throws, and always returns a handle. A synchronous rejection — unknown key, invalid config, missing anchor — returns an already settled presentation, so the caller has one code path either way.
Returns synchronously, and must keep doing so: the handle is a
receipt, not an answer. The answer arrives later on
CampaignPresentation.outcome. A plugin needs its synchronous grip on
the handle because a CEP can close a template milliseconds after
presenting it — without it, cancel() would be racy and the plugin would
need a side-map to correlate CEP context with a handle that arrives later.
Implementation
@override
CampaignPresentation deliver(CEPTriggerPayload trigger) {
final plugin = _activePlugin;
final controller = _coordinator.open(
trigger,
owner: plugin?.id ?? '<detached>',
);
// Before the state gate, so a trigger that is refused outright still shows
// up on the timeline as having arrived. "Nothing happened at all" and "it
// arrived and we turned it away" are the two answers a campaign creator
// most needs to tell apart.
observeDelivery(controller);
if (plugin == null) {
// A CEP callback that outlived its plugin. Settling immediately is what
// makes the handle total: the caller awaits the same outcome it would
// for any other rejection.
controller.settle(const PresentationDropped(
reason: DropReason.pluginDetached,
detail: 'no plugin is attached',
));
return controller.presentation;
}
final driver = CepDriver(plugin.id);
// Nothing is held before ready (startup plan SP5): the trigger settles at
// once, which hands the CEP its slot back.
final drop = _preReadyDrop();
if (drop == null) {
// A CEP trigger must not show a campaign that Digia decides itself.
if (_services?.campaignStore.find(trigger.campaignKey)?.rule != null) {
controller.settle(const PresentationDropped(
reason: DropReason.digiaManaged,
detail: 'Digia decides this campaign',
));
return controller.presentation;
}
_routeDelivered(controller, driver);
} else {
final (reason, detail) = drop;
_log.w('Dropped — $detail', campaign: trigger.campaignKey);
controller.settle(PresentationDropped(reason: reason, detail: detail));
}
return controller.presentation;
}