Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send last sent message to new consumer on a jms topic

Tags:

jms

activemq

Is it possible to configure the topic to store a copy of just the last message and send this to new connections without knowing client identifiers or other info?

Update: From the info provided by Shashi I found this two pages where they describe a use case similar to mine (applied over stock prices) by using retroactive consumer and a subscription recovery policy. How ever I'm not getting the desired behaviour. What I currently do is:

Include in the activemq the folowing lines in the policyEntry for topic=">"

<subscriptionRecoveryPolicy>
  <fixedCountSubscriptionRecoveryPolicy maximumSize="1"/> 
</subscriptionRecoveryPolicy>

Add to the URL used to connect to the brocker (using activemq-cpp) consumer.retroactive=true.

Set the consumer has durable. (But I strongly think this is not want since I only need the last one, but without it I didn't get any message when starting the consumer for the second time)

  1. Start up the broker.

  2. Start the consumer.

  3. Send a message to the topic using the activemq web admin console. (I receive it in the consumer, as expected)

  4. Stop consumer.

  5. Send another message to the topic.

  6. Start consumer. I receive the message, also as expected.

However, if the consumer receives a message, then it goes offline (stop process) and then I restart it, it doesn't get the last message back.

The goal is to whenever the consumer starts get the last message, no mater what (obviously, except when there weren't messages sent to the topic).

Any ideas on what I'm missing?

Background:

I have a device which publishes his data to a topic when ever its data changes. A variable number of consumer may be connected to this topic, from 0 to less than 10. There is only one publisher in the topic and always publish all of his data as a single message (little data, just a couple of fields of a sensor reading). The publication rate of this information is variable, not necessarily time based, when something changes a new updated message is sent to the broker. The problem is that when a new consumer connects to the topic it has no data of the device readings until a new message is send to the topic by the device. This could be solve by creating an additional queue so new connections can subscribe to the topic and then request the device for the current reading through the queue (the device would consume the queue message which would be a request for data, and then response in the same queue). But Since the messages send to the topic are always information complete I was wondering if is it possible to configure the topic to store a copy of just the last message and send this to new connections without know client identifiers or other info?

Current broker in use is ActiveMQ.

like image 763
Javier Mr Avatar asked Oct 20 '22 13:10

Javier Mr


1 Answers

What you want is to have retroactive consumers and to set the lastImageSubscriptionRecoveryPolicy subscription recovery policy on the topic. Shashi is correct in saying that the following syntax for setting a consumer to be retroactive works only with Openwire

topic = new ActiveMQTopic("TEST.Topic?consumer.retroactive=true");

In your case, what you can do is to configure all consumers to be retroactive in broker config with alwaysRetroactive="true". I tested that this works even for the AMQP protocol (library qpid-jms-client) and I suspect it will work for all protocols.

<destinationPolicy>
  <policyMap>
    <policyEntries>
      <policyEntry topic="FOO.>" alwaysRetroactive="true">
        <subscriptionRecoveryPolicy>
          <lastImageSubscriptionRecoveryPolicy />
        </subscriptionRecoveryPolicy>
      </policyEntry>

The configuration example is taken from https://github.com/apache/activemq/blob/master/activemq-unit-tests/src/test/resources/org/apache/activemq/test/retroactive/activemq-message-query.xml

like image 175
user7610 Avatar answered Oct 27 '22 23:10

user7610