-
|
I have a question about how delays are applied when using a combined command handler (DB + AMQP) together with the Delayed attribute and a custom delay passed via metadata. Scenario I have a command handler that is configured as a combined handler (DB + AMQP) and has a #[Asynchronous('combined')]
#[CommandHandler('fee.complete', 'id.fee.complete')]
#[Delayed(new TimeSpan(seconds: 15))]
public function handle(
array $data,
#[Header('isRepeat')]
bool $isRepeat = false,
): void {
// some work...
// then I send another command with a custom delay
$this->commandBus->sendWithRouting(
routingKey: 'fee.complete',
command: $data,
metadata: [
MessageHeaders::DELIVERY_DELAY => new TimeSpan(minutes: 30),
'isRepeat' => true,
],
);
}The handler itself is combined (DB + AMQP), and I also specify a delay inside the handler when sending a new message via the command bus, using metadata. Question Which delay is supposed to have higher priority in this case? The delay defined on the handler via the Right now it looks like the custom delay from metadata is being ignored when the message is sent from inside such a combined handler. The behavior I observe is that the Delayed attribute delay (e.g., 15 seconds) is used, even if I pass a different delay in metadata when sending the message. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
|
I’ve checked the implementation of if ($delayed) {
$metadata[MessageHeaders::DELIVERY_DELAY] = $delayed->getHeaderValue();
if ($delayed->getExpression()) {
$metadata[MessageHeaders::DELIVERY_DELAY] = $this->expressionEvaluationService->evaluate($delayed->getExpression(), [
'payload' => $message->getPayload(),
'headers' => $message->getHeaders()->headers(),
]);
}
$type = Type::createFromVariable($metadata[MessageHeaders::DELIVERY_DELAY]);
if (! $type->isCompatibleWith(UnionType::createWith([
Type::int(),
Type::object(TimeSpan::class),
Type::object(DateTimeInterface::class),
]))) {
throw ConfigurationException::create("Delivery delay should be either integer, TimeSpan or DateTimeInterface, but got {$type->toString()}");
}
}From this code it looks like: This means that any custom delay that I set explicitly in metadata (e.g. when sending a command via the command bus) gets overwritten by the handler-level Delayed configuration. The same concern applies to other headers such as Questions / suggestion Is this overriding behavior intentional, so that endpoint-level Delayed configuration always has priority over whatever is set in metadata? Would it be possible (or acceptable) to change this behavior so that: if a This would allow a more flexible usage where: handler-level attributes ( If the current behavior is intentional, maybe there could be: either a configuration option to control priority (metadata vs attribute), or a dedicated attribute/flag to tell the interceptor “do not override existing headers, only set them when missing”. |
Beta Was this translation helpful? Give feedback.
I’ve checked the implementation of
EndpointHeadersInterceptorand noticed the following logic: