[ 
https://issues.apache.org/jira/browse/CAMEL-25855?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Claus Ibsen resolved CAMEL-25855.
---------------------------------
    Resolution: Fixed

> camel-quickfix - an InOut request that times out or cannot be sent leaves its 
> correlation rule and exchange in the engine for good
> ----------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25855
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25855
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-quickfix
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Major
>             Fix For: 4.24.0
>
>
> For an InOut exchange, {{QuickfixjProducer.sendMessage}} registers a 
> correlation rule (the exchange and its {{CorrelationCriteria}}) in the 
> {{MessageCorrelator}} of the engine before it sends the FIX message, then 
> waits for the reply up to {{CorrelationTimeout}} (default 1000 ms). 
> {{MessageCorrelator}} removes a rule only in {{onEvent}}, when a message that 
> matches its criteria arrives:
> {code:java}
> for (MessageCorrelationRule rule : rules) {
>     if (rule.getMessageCriteria().evaluate(message)) {
>         rule.setReplyMessage(message);
>         rules.remove(rule);
>         rule.getLatch().countDown();
>     }
> }
> {code}
> So a rule stays registered for good, holding its exchange, when:
> * the wait times out and no matching message ever arrives (the counterparty 
> answers with a session level Reject or a BusinessMessageReject that the 
> criteria do not match, or does not answer at all);
> * the send fails: {{Session.send}} returns false (session not logged on, the 
> producer throws {{CannotSendException}}) or throws. The exchange fails, so 
> nobody waits for a reply (QuickFIX/J has stored an application message before 
> it found the session not logged on, and may still resend it after the next 
> logon).
> The rules are kept in a {{CopyOnWriteArrayList}} of the engine, which lives 
> as long as the component, so they add up for every such request (a route that 
> retries InOut sends while the session is down adds one per attempt). Each add 
> copies the whole list, and every FIX message the engine receives or sends 
> (application and admin messages, heartbeats) is evaluated against every 
> leaked rule on the session thread.
> *Fix*: the waiting {{Callable}} removes its rule in a finally block (reply, 
> timeout or interrupt), and the producer removes the rule of an exchange whose 
> send failed (new {{MessageCorrelator.cancelReply(Exchange)}}). The rule is 
> still registered before the send, so a fast reply is not missed.
> *Tests*: new {{QuickfixjProducerCorrelationCleanupTest}} (3 tests, same 
> mocked session as {{QuickfixjProducerTest}}). On main: 
> {{timedOutRequestsDoNotStayRegistered}} (50 InOut requests with a 10 ms 
> timeout and no reply) fails with {{correlation rules left after 50 timed out 
> requests ==> expected: <0> but was: <50>}}; 
> {{requestThatCannotBeSentDoesNotStayRegistered}} and 
> {{requestWhoseSendThrowsDoesNotStayRegistered}} fail with {{expected: <0> but 
> was: <1>}}. All pass with the fix. camel-quickfix unit tests with the fix: 46 
> run, 0 failures (including the existing InOut tests of 
> {{QuickfixjProducerTest}}).
> *How it was found*: a review of request/reply correlation in producers (where 
> a waiting request is registered and where it is removed again). The JUnit 
> tests above are the evidence; it was not run against a FIX counterparty.
> *Affected*: main, camel-4.23.x, camel-4.22.x, camel-4.18.x and camel-4.14.x 
> (same {{MessageCorrelator}} and {{QuickfixjProducer}}; read, not run).
> _Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to