Particular / NServiceBus.AzureServiceBus

The Azure ServiceBus Transport
https://docs.particular.net/nservicebus/azure-service-bus/
Other
13 stars 17 forks source link

Individul message TimeToBeReceived higher than entity default TimeToLive is truncated #81

Closed SeanFeldman closed 8 years ago

SeanFeldman commented 8 years ago

By default, when an entity is created (queue for example) we set entity TTL to TimeSpan.MaxValue. Users can override that setting through AzureServiceBusResourceExtensions extension points and specify a custom TTL value for an entity TTL directly or via by specifying a custom entity factory using QueueDescriptionFactory.

Example:

// endpoint configuration
busConfiguration.UseTransport<AzureServiceBusTransport>()
 .UseDefaultTopology().Resources().Queues().DefaultMessageTimeToLive(TimeSpan.FromMinutes(5));

Message can have a TTBR that is lower than the entity default TTL, which will be applied to the outgoing BrokeredMessages

// message
[TimeToBeReceived("10:10:10")]
public class MyMessage : IMessage {}

ASB will accept the message,

image

but message TTL will be auto-updated to match the lower value of the entity image

SeanFeldman commented 8 years ago

@Particular/azure I suspect this could lead to a message loss.

Scenario: If message is set to be processed within time X, queue is configured with default TTL Y (where Y < X), and endpoint is down for Z time (where Y < Z < X), message will be expired by ASB and therefore will never get delivered.

While this is an edge case, it is possible, especially with no validation of individual messages TTBR against entity TTL.

SeanFeldman commented 8 years ago

We should log if possible.

abombss commented 8 years ago

+1 to logging when it occurs if possible, that would require periodically reading the entity description to get the TTL that is set since the user can override it directly in ASB.

Message loss can be prevented if you set the flag to send expired messages to the dead letter queue. But then again, if I am setting TTL I have to be willing / able to support message loss. This is a total edge case but certainly a difficult one to figure out / debug if its happening from a poor configuration.

SeanFeldman commented 8 years ago

After some thought I've realized that this is a problem with ASB library. As a sender of a message to some queue, I don't want to query that queue`s default TTL. So setting a message with a much higher TTL and sending to a queue with a lower TTL should result in exception thrown by ASB. As of today, ASB library allows you to make this send and re-writes message TTL.

Either throwing exception or allowing to control the behaviour on the ASB level is what should be done IMO. I've raised this issue with MSFT @abombss

LiamFeldman commented 8 years ago

In MSFT ASB team opinion, entity level TTL is decided by administrators, not the developers. That actually makes things even more interesting, as developers might be not in sync with the IT (things happen) and that will result in message level TTL higher than entity TTL.

I have suggested to be able to configure ASB client to throw exception when this situation occurs, but don't know if this will be accepted or not.

SeanFeldman commented 8 years ago

Workaround is to enable setting to sent DLQ on message expiry on the entities, but it will not provide the reason/explanation.

SeanFeldman commented 8 years ago

This can happen, but we can't prevent it automatically. DLQ on message expiry should be enabled.