Andrea Cosentino created CAMEL-25160:
----------------------------------------

             Summary: camel-mongodb - harden the persistent tail tracking 
manager
                 Key: CAMEL-25160
                 URL: https://issues.apache.org/jira/browse/CAMEL-25160
             Project: Camel
          Issue Type: Bug
          Components: camel-mongodb
            Reporter: Andrea Cosentino
            Assignee: Andrea Cosentino


h3. Summary

Two small robustness problems in {{MongoDbTailTrackingManager}}, both on the 
persistent tail tracking
path ({{persistentTailTracking=true}}).

h3. The update filter grows, defeating the stated optimisation

{{initialize()}} deliberately reduces the tracking document to its id:

{code:java}
// keep only the _id, the rest is useless and causes more overhead during update
trackingObj = new Document(MONGO_ID, trackingObj.get(MONGO_ID));
{code}

and {{persistToStore()}} immediately undoes it, because it stores the full 
updated document back:

{code:java}
FindOneAndUpdateOptions options = new 
FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER);
trackingObj = dbCol.findOneAndUpdate(trackingObj, updateObj, options);
{code}

>From the first persist onwards the filter is {{{_id, <field>: <previous 
>value>}}} rather than
{{{_id}}}. That is self-consistent for a single writer, but if anything else 
changes that field - two
routes configured with the same {{persistentId}}, or an external writer - the 
update matches nothing,
{{findOneAndUpdate}} returns {{null}}, and the *next* call passes a null filter.

That throws from the {{finally}} of {{MongoDbTailingThread.doRun()}}, which 
lands in the consumer
thread's catch, regenerates the cursor and persists again: the same 
non-terminating shape as
CAMEL-25025.

h3. recoverFromStore does not guard against a missing document

{code:java}
lastVal = dbCol.find(trackingObj).first().get(config.field);
{code}

{{first()}} returns {{null}} if the tracking document has gone between 
{{initialize()}} and this call.

h3. Proposed fix

Keep filtering by {{_id}} only, and null-guard the recovery read. Note also 
that the {{ReentrantLock}} in
this class guards state that only the single consumer thread touches, so it is 
redundant rather than
wrong - worth leaving alone unless it is confusing.

----
_Reported by Claude Code on behalf of oscerd (Andrea Cosentino)._



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to