How to remove posts from a topic

I am trying to write an application using the JMS publish subscription model. However, I encountered a failure, I want the publisher to delete posts from the topic. Usecase is that I have reliable subscribers who will receive active messages (since they are more or less instantly), but if there are inactive ones and the publisher decides that the message is incorrect, I want him to be able to delete the message so that the subscribers no longer will receive it after they become active. The problem is that I do not know how to do this. For the provider, I settled on the implementation of glass fish, but if other alternatives offer this functionality, I can switch.

Thanks.

+4
source share
3 answers

JMS is a form of asynchronous messaging, and so publishers and subscribers are design-decoupled. This means that there is no mechanism for doing what you ask. For subscribers who are active at the time of publication, they will use the message without any chance of receiving a deletion message in time to act on it. If the subscriber is offline, they will, but asynchronous messages must be atomic. If you start developing the response of another respondent (create a message about deleting and ask to reconnect consumers to read the entire queue that requires deleting messages), then you will create a situation in which the behavior of the system will differ depending on whether the subscriber was online or not when a particular message / deletion combination was published. There is also a race condition in which the subscriber finishes reading the stored messages immediately before the publisher sends the delete message. This means that you must put significant logic in the subscribers to agree on these conditions and even more to agree on the state of the race.

The accepted way to do this is through so-called “countervailing transactions”. In any system where the manufacturer and the consumer do not share a single work unit or do not have a common state (for example, using the same database to store the state), a second transaction is required to return or correct the previous transaction, which changes the first. Of course, the consumer must correctly apply the compensation transaction. When this template is used, the result is that all subscribers exhibit the same behavior regardless of whether messages are consumed in real time or in a batch after a consumer reboot.

Please note that the compensation transaction is different from the “delete message”. The delete message proposed in the response of another respondent is a form of command and control that affects the flow of messages. On the other hand, countervailing transactions affect the state of the system through transactional updates to the state of the system.

As a rule, you never want to control the state of the system by controlling the flow of messages using the management and management functions. It is fragile, susceptible to attack and very difficult to audit or debug. Instead, create a system to deliver each message depending on the quality of service and processing of all messages. Changes in the state of the pens (including a change in the previous action) are completely in the application.

As an example, in banking, where transactions cause secondary effects, such as overdraft fees, the general procedure is to “replace” transactions throughout the day, and then sort and apply them in batches after the bank closes. This allows you to put up with the error before it leads to the collection of an overdraft. More recently, transactions are applied in real time, but triggers are held until the day books are closed, and this achieves the same result.

+6
source

JMS API does not allow deleting messages from any addressee (either in the queue or in the subject). Although I believe that certain JMX providers provide their own tools for managing their state, for example, using JMX. Try to verify this for your JMS provider, but be careful: even if you find a solution, it will not be portable between different JMS providers.

One legitimate way to “delete” a message is to use time for life: publish(Topic topic, Message message, int deliveryMode, int priority, long timeToLive) . This is probably enough for you.

If this is not applicable for your application, solve the problem at the application level. For example, attach a unique identifier to each message and publish a special “delete” message with a higher priority, which will be a kind of command to delete a “real” message with the same identifier.

+1
source

You have a manufacturer sending a delete message, and the consumer must read all messages before proceeding to process them.

-1
source

Source: https://habr.com/ru/post/1383275/


All Articles