My application is using Messaging (53). If a Messages (66) data or request is not received by a certain time, it is useless and should be ignored.
How can a sender indicate when a message should be considered stale and thus shouldn’t be processed?
Messaging (53) practically guarantees that the Message (66) will eventually be delivered to the receiver. What it cannot guarantee is how long the delivery may take. For example, if the network connecting the sender and receiver is down for a week, then it could take a week to deliver a message. Messaging is highly reliable, even when the participants (sender, network, and receiver) are not, but messages can take a very long time to transmit in unreliable circumstances. (For more details, see Guaranteed Delivery .)
Often, a message’s contents have a practical limit for how long they’re useful. A caller issuing a stock quote request probably loses interest if it does not receive an answer within a minute or so. That means the request should not take more than a minute to transmit but also that the answer had better transmit back very quickly. A stock quote reply more than a minute or two old is probably too old and therefore irrelevant.
Once the sender sends a message and does not get a reply, it has no way to cancel or recall the message. Likewise, a receiver could check when a message was sent and reject the message if it’s too old, but different senders under different circumstances may have different ideas about how long is too long, so how does the receiver know which messages to reject? What is needed is a way for the sender to specify the message’s lifetime.
Figure 5.12 Set the Message Expiration to specify a time limit for how long the message is viable.
Once the time for which a message is viable passes, and the message still has not been consumed, then the message will expire. The messaging system’s consumers will ignore an expired message; they treat the message as if it where never sent in the first place. Most messaging system implementations reroute expired messages to the Dead Letter Channel (119), whereas others simply discard expired messages; this may be configurable.
A Message Expiration is like the expiration date on a milk carton. After that date, you shouldn’t drink the milk. Likewise, when a message expires, the messaging system should no longer deliver it. If a receiver still receives a message but cannot process it before the expiration, the receiver should throw away the message.
A Message Expiration is a timestamp (date and time) that specifies how long the message will live or when it will expire. The setting can be specified in relative or absolute terms. An absolute setting specifies a date and time when the message will expire. A relative setting specifies how long the message should live before it expires; the messaging system will use the time when the message is sent to convert the relative setting into an absolute one. The messaging system is responsible for adjusting the timestamp for receivers in different time zones from the sender, for adjustments in daylight savings times, and any other issues that can keep two different clocks from agreeing on what time it is.
The message expiration property has a related property, sent time, which specifies when the message was sent. A message’s absolute expiration timestamp must be later than its sent timestamp (or else the message will expire immediately). To avoid this problem, senders usually specify expiration times relatively, in which case the messaging system calculates the expiration timestamp by adding the relative timeout to the sent timestamp (expiration time = sent time + time to live).
When a message expires, the messaging system may simply discard it or may move it to a Dead Letter Channel (119). A receiver that finds itself in possession of an expired message should move it to the Invalid Message Channel (60). With a Publish-Subscribe Channel (106), each subscriber gets its own copy of the message; some copies of a message may reach their subscribers successfully, whereas other copies of the same message expire before their subscribers consume them. When using Request-Reply (154), a reply message with an expiration setting may not work well—if the reply expires, the sender of the request will never know whether the request was ever received in the first place. If reply expirations are used, the request sender has to be designed to handle the case where expected replies are never received.
Example: JMS Time-to-Live Parameter
Message expiration is what the JMS specification calls “message time-to-live” [JMS 1.1], [Hapner]. JMS messages have a predefined property for message expiration, JMSExpiration, but a sender should not set it via Message.setJMSExpiration(long) because the JMS provider will override that setting when the message is sent. Rather, the sender should use its MessageProducer (QueueSender or TopicPublisher) to set the timeout for all messages it sends; the method for this setting is MessageProducer.setTimeToLive(long). A sender can also set the time-to-live on an individual message using the MessageProducer.send(Message message, int deliveryMode, int priority, long timeToLive) method, where the fourth parameter is the time-to-live in milliseconds. Time-to-live is a relative setting specifying how long after the message is sent it should expire.
Example: .NET Time-to-Be-Received and Time-to-Reach-Queue Properties
A .NET Message has two properties for specifying expiration: TimeToBeReceived and TimeToReachQueue. The reach-queue setting specifies how long the message has to reach its destination queue, after which the message might sit in the queue indefinitely. The be-received setting specifies how long the message has to be consumed by a receiver, which limits the total time for transmitting the message to its destination queue plus the amount of time the message can spend sitting on the destination queue. TimeToBeReceived is equivalent to JMS’s JMSExpiration property. Both time settings have a value of type System.TimeSpan, a length of time [SysMsg], [Dickman].