How to handle multiple threads in listenener?
Hi,
We had a requirement to listen for every modification of an asset and send the asset details to the client API. Since each modification generates multiple events, we added a map to check if the path already exists; if it does, the API should not be triggered. However, sometimes the map fails to update due to multiple threads running concurrently.
private static final ConcurrentHashMap<String, Long> processedPaths = new ConcurrentHashMap<>();
For the event path(sling:members node change) - thread id:185
/content/dam/projects/product-images/mixedmediasets/img-1/jcr:content/related/s7Set/sling:members
The processedPaths map contains:
{ /content/dam/projects/product-images/temporary-imageset-folder/img-2 = 1741863896578 } - ( old data- previous executed gtin)
During the if condition check, it verifies whether the event path- img-1 exists in processedPaths and time is > or < 30sec.
(Checking for path: /content/dam/projects/product-images/mixedmediasets/img-1, lastProcessedTime: null, currentTime: 1741865497219).
Since it does not contain img-1 hence last processedTime is null , the code proceeds to check if the timestamp for existing map entry (i.e. processed GTINs) is more than 30 seconds old.
If true, then it removes the existing entry i.e img-2>30sec from processedPaths keeping latest in record i.e. img-1 as new entry.
Logs shows old GTIN got removed :
(Removing entry: /content/dam/projects/product-images/temporary-imageset-folder/img-2, lastProcessedTime: 1741863896578).
Then, it adds the new event path with the current timestamp as below:
{ /content/dam/projects/product-images/mixedmediasets/img-1 = 1741865497247 } and trigger the sling job and call glass API.
-----------------------------------------------------------------------------------------------------------------------------------
Again, For the event path(metadata) new thread id:204
/content/dam/projects/product-images/mixedmediasets/img-1/jcr:content/metadata
processedPaths does not get updated with the new resourcePath. It still contains the previous entry
( Here is the issue as map is thread safe it should have updated data but still contain old data even it was updated in previous thread)
Logs shows processed path as:
{ /content/dam/projects/product-images/temporary-imageset-folder/img-2 = 1741863896578 }
As a result, when the if condition checks whether /content/dam/projects/product-images/mixedmediasets/img-1 exists in processedPaths, the condition fails. Consequently, the Sling job is triggered again and API called again.
how to handle this? We have made the add and remove to map synchronized.
Thank you.
