'Producer program will not recreate an address in Artemis once automatically deleted
Now that I managed to get the address to auto delete (based on this question) I cannot figure out what is preventing my producer from recreating the address.
When there's no producer pushing data to a specific address I need it to auto delete. Right now when the last consumer disconnects the address gets deleted, and the producer will not recreate the address.
Below is the producer code. It's just a simple Java function that reads a value from an XML message and uses that as the address name. It's basically sorting the messages into different topics based on the name in the XML message itself:
/////////////////////////////////////
//Constructor to establish connection
/////////////////////////////////////
public ActiveMQ(String amq_url) throws JMSException, NamingException{
jndi_env = new Hashtable<String, Object>();
jndi_env.put(InitialContext.INITIAL_CONTEXT_FACTORY, "org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory");
jndi_env.put(InitialContext.PROVIDER_URL, amq_url);
ic = new InitialContext(jndi_env);
connectionFactory = (ConnectionFactory) ic.lookup("ConnectionFactory");
this.connection = (ActiveMQConnection) connectionFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
/////////////////////////////////////
//Switch address to publish to
/////////////////////////////////////
public void useAddress(String addressName) throws JMSException, NamingException{
if (producer != null) producer.close();
this.address= (Destination) ic.lookup("dynamicTopics/"+addressName);
this.producer = session.createProducer(address);
}
The only way to get this line of code to make the address again is to restart the producer program or the Artemis server. I've tried having the logic completely close everything and re-open it (session, connection, etc) and that didn't fix it. Is there a setting that I'm missing here? I can't find anything in the documentation that covers why the address is not being recreated by the producer. Any help would be appreciated!
broker.xml
(same as from other question):
<address-setting match="#">
<dead-letter-address>DLQ</dead-letter-address>
<expiry-address></expiry-address>
<redelivery-delay>0</redelivery-delay>
<expiry-delay>10</expiry-delay>
<max-size-bytes>-1</max-size-bytes>
<max-size-messages>-1</max-size-messages>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
<address-full-policy>PAGE</address-full-policy>
<auto-create-queues>true</auto-create-queues>
<auto-create-addresses>true</auto-create-addresses>
<auto-delete-queues>true</auto-delete-queues>
<auto-delete-addresses>true</auto-delete-addresses>
<auto-delete-created-queues>true</auto-delete-created-queues>
<auto-delete-queues-message-count>-1</auto-delete-queues-message-count>
</address-setting>
EDIT: So there really isn't an easy way to do this with the settings in Artemis alone. I think the best solution for what I need, based on Justin's answer below, is to turn off auto-delete settings and do this through java programming, using something similar to my other question where I read the available addresses, and delete the ones that arent relevant anymore.
For now, setting a long delay using <auto-delete-address-delay>
will suit my current needs temporarily.
Solution 1:[1]
I believe this is an edge case that isn't covered currently.
When you create a named producer (e.g. using javax.jms.Session.createProducer(Destination)
) or send a message to a destination with an anonymous producer (e.g. using javax.jms.MessageProducer.send(Destination, Message)
) the client checks to see if the destination exists. If the destination doesn't exist then the client will create it if the proper auto-create settings are true
. The client then caches this information so that it doesn't have to keep checking every time it sends a message to the destination in question as checking every time would be prohibitively time consuming. Of course, not checking means the destination can go away and the client wouldn't know.
When you restart the application and the producer is created again the address gets re-created.
It's not clear why you need the address to be deleted when no producer is actively pushing messages to it. In general I would say that your use-case doesn't fit well with auto-delete. Auto-delete was really designed for use-cases involving single-use or ephemeral destinations. The address definition in memory consumes very few resources so generally speaking it's fine to just leave it. I recommend you disable auto-delete (as it is by default) to mitigate this issue for now.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Justin Bertram |