Skip to content

JAMES-4192 Merge Artemis delayed queue improvements with latest master - #3230

Open
prosgarz35 wants to merge 2 commits into
apache:masterfrom
Hollow-Ataraxia:JAMES-4192-merged
Open

prosgarz35 wants to merge 2 commits into
apache:masterfrom
Hollow-Ataraxia:JAMES-4192-merged

Conversation

@prosgarz35

Copy link
Copy Markdown
Contributor

No description provided.

@prosgarz35 prosgarz35 mentioned this pull request Oct 3, 2026
@prosgarz35

Copy link
Copy Markdown
Contributor Author

artemis -> activemq renaming for better backward compability

@prosgarz35
prosgarz35 marked this pull request as ready for review October 6, 2026 02:31

@chibenwa chibenwa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR reverts parts of master, weakens durability by default, and its delayed-queue design causes heavy journal churn.


The idea (a companion -delayed queue, and no selector on the main queue) is sound. The implementation has problems:

  • Very heavy write churn. Every 200 ms the transfer task drains up to 1000 messages and re-sends every message that isn't due yet, full MIME body included. Each delayed mail is
    rewritten to the journal 5 times per second. With 1000 delayed mails of 100 KB, that's about 500 MB/s of journal writes. The javadoc calls the interval "coarse", but 200 ms is not.
  • Memory. Up to 1000 full messages are held in memory on every pass.
  • Thread safety. enQueueDelayed calls delayedSession.createObjectMessage() outside the synchronized (delayedProducer) block. A JMS Session isn't thread-safe, and enqueues are
    concurrent.
  • send(copy, mode, prio, m.getJMSExpiration()) passes an absolute expiration timestamp where the API expects a relative time-to-live. It's harmless while expiration is 0, but wrong.
  • remove() on the delayed queue uses a selector. That's the same paging limitation the PR sets out to avoid. The value is also concatenated without escaping ', % and _.
  • removeFromDelayedQueue waits receive(2000), so every clear() or remove() takes at least 2 s even when the delayed queue is empty.
  • One extra thread per queue for the transfer task.
  • Rejected alternatives aren't evaluated. The PR dismisses Artemis native scheduled delivery because of browse()/getSize() limits, but doesn't consider a non-polling design (for
    example, delayed queues bucketed by delivery time).

Comment thread server/queue/queue-jms/pom.xml Outdated
Comment on lines +100 to +104
<groupId>org.apache.artemis</groupId>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jakarta-client</artifactId>
</dependency>
<dependency>
<groupId>org.apache.artemis</groupId>
<groupId>org.apache.activemq</groupId>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oups ?

Comment thread pom.xml
Comment on lines -4606 to -4616
<profile>
<id>windows-git</id>
<activation>
<os>
<family>windows</family>
</os>
</activation>
<properties>
<git.useNativeGit>false</git.useNativeGit>
</properties>
</profile>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oups ?

Comment on lines +34 to +53
@@ -47,10 +47,10 @@ public class ActiveMQConfiguration {
private static final boolean ASYNC_CONNECTION_EXECUTION_DEFAULT = true;

private static final String CLIENT_BLOCK_ON_DURABLE_SEND = "artemis.client.block.on.durable.send";
private static final boolean CLIENT_BLOCK_ON_DURABLE_SEND_DEFAULT = true;
private static final boolean CLIENT_BLOCK_ON_DURABLE_SEND_DEFAULT = false;

private static final String CLIENT_BLOCK_ON_ACKNOWLEDGE = "artemis.client.block.on.acknowledge";
private static final boolean CLIENT_BLOCK_ON_ACKNOWLEDGE_DEFAULT = true;
private static final boolean CLIENT_BLOCK_ON_ACKNOWLEDGE_DEFAULT = false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wekeans durability !

attrValue = message.getObjectProperty(name);
}
} catch (Exception e) {
} catch (JMSException e) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why ?

catch (Exception) → catch (JMSException) in mailAttribute narrows the catch. A runtime exception (deserialization, for example) will now propagate instead of being logged, which can break dequeueing

// Dequeue should instantly receive the ready message without head-of-line blocking
reactor.core.publisher.Mono<org.apache.james.queue.api.MailQueue.MailQueueItem> itemMono =
reactor.core.publisher.Flux.from(mailQueue.deQueue()).next();
org.apache.james.queue.api.MailQueue.MailQueueItem dequeuedItem =

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use imports

@prosgarz35

Copy link
Copy Markdown
Contributor Author

@chibenwa i fixed this :)

@chibenwa

Copy link
Copy Markdown
Contributor

Hello @prosgarz35

The latest 1d87744 commit handles only fixes for inline comments but do not seem to address #3230 (review)

Cosmetic issues are addressed; fine.

We would now need core design issue to get more work before being able to merge.

Would you be able to push this work further?

Best regards,

Benoit TELLIER

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants