Skip to content

Commit 1a08bd8

Browse files
authored
Fix concurrent processing error (#479)
* Handle concurrent access issues. * Version bump. * Update release notes
1 parent 76e329b commit 1a08bd8

5 files changed

Lines changed: 52 additions & 32 deletions

File tree

RELEASE-NOTES.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
# OpenAS2 Server
2-
# Version 4.6.2
2+
# Version 4.6.3
33
# RELEASE NOTES
44
-----
5-
The OpenAS2 project is pleased to announce the release of OpenAS2 4.6.2
5+
The OpenAS2 project is pleased to announce the release of OpenAS2 4.6.3
66

7-
The release download file is: OpenAS2Server-4.6.2.zip
7+
The release download file is: OpenAS2Server-4.6.3.zip
88

99
The zip file contains a PDF document (OpenAS2HowTo.pdf) providing information on installing and using the application.
1010
## NOTE: Testing covers Java 11 to 21.
1111
## Java 8 is NO LONGER SUPPORTED.
1212

13-
Version 4.6.2 - 2025-09-27
13+
Version 4.6.3 - 2025-09-29
1414

1515
This is a bugfix release.
16-
1. Enhanced the poller algorithm to avoid race conditions under very high volume file processing.
16+
1. Avoid concurrent processing error that occurs after files after sent as part of the cleanup process.
1717

1818

1919
##Upgrade Notes

Server/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<!-- DO NOT CHANGE THIS "groupId" WITHOUT CHANGING XMLSession.getManifestAttributes.MANIFEST_VENDOR_ID_ATTRIB -->
88
<groupId>net.sf.openas2</groupId>
99
<artifactId>OpenAS2</artifactId>
10-
<version>4.6.2</version>
10+
<version>4.6.3</version>
1111
<relativePath>../pom.xml</relativePath>
1212
</parent>
1313

Server/src/main/java/org/openas2/processor/receiver/DirectoryPollingModule.java

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ public abstract class DirectoryPollingModule extends PollingModule {
3838
private Map<String, Long> trackedFiles = new HashMap<String, Long>();
3939
// Files that have been passed to a processor - key is the absolute file path and value is the processing start timestamp
4040
private Map<String, Long> processingFiles = new HashMap<String, Long>();
41+
// Files that have been processed in thread mode and need removing from the tracked files maps by the main thread
42+
Collection<String> threadProcessedFiles = Collections.synchronizedCollection(new ArrayList<String>());
4143

4244
private String errorDir = null;
4345
private String sentDir = null;
@@ -217,24 +219,37 @@ protected void processSingleFile(File file, String fileEntryKey) {
217219
//forceStop(e1);
218220
return;
219221
}
220-
} finally {
221-
// Remove trackedFiles entry first to avoid race condition in parallel processing
222-
trackedFiles.remove(fileEntryKey);
223-
processingFiles.remove(fileEntryKey);
224-
}
222+
}
225223
}
226224

227-
protected void triggerFileProcessing(File file, String fileEntryKey) {
228-
// Add the in processing flag on the file now otherwise in threaded mode there is a race condition
229-
processingFiles.put(fileEntryKey, System.currentTimeMillis());
230-
if (processFilesAsThreads) {
231-
processFileInThread(file, fileEntryKey);
232-
} else {
233-
processSingleFile(file, fileEntryKey);
225+
private void processFileInThread(File file, String fileEntryKey) {
226+
if (logger.isDebugEnabled()) {
227+
logger.debug("Parallel processing mode handling file: " + file.getName());
234228
}
229+
executorService.execute(new Runnable() {
230+
@Override
231+
public void run() {
232+
try {
233+
processSingleFile(file, fileEntryKey);
234+
} finally {
235+
// Add to list for removal from tracking maps when updateTracking is called
236+
threadProcessedFiles.add(fileEntryKey);
237+
}
238+
}
239+
});
235240
}
236241

237242
private void updateTracking() {
243+
// first remove processed files if we are running in parallel processing mode to avoid concurrency issues
244+
if (processFilesAsThreads) {
245+
synchronized (threadProcessedFiles) {
246+
threadProcessedFiles.forEach((fileEntryKey) -> {
247+
trackedFiles.remove(fileEntryKey);
248+
processingFiles.remove(fileEntryKey);
249+
});
250+
threadProcessedFiles.clear();
251+
}
252+
}
238253
// Use an iterator to be able to remove entries whilst iterating over the map.
239254
Iterator<Map.Entry<String, Long>> iter = trackedFiles.entrySet().iterator();
240255
while (iter.hasNext()) {
@@ -264,24 +279,24 @@ private void updateTracking() {
264279
trackedFiles.put(fileEntryKey, Long.valueOf(newLength));
265280
} else {
266281
// no change in file length so process the file
267-
triggerFileProcessing(file, fileEntryKey);
282+
// Add the processing flag on the file now otherwise in threaded mode there is a race condition
283+
processingFiles.put(fileEntryKey, System.currentTimeMillis());
284+
if (processFilesAsThreads) {
285+
processFileInThread(file, fileEntryKey);
286+
} else {
287+
try {
288+
processSingleFile(file, fileEntryKey);
289+
} finally {
290+
iter.remove();
291+
processingFiles.remove(fileEntryKey);
292+
}
293+
}
294+
268295
}
269296
}
270297
}
271298
}
272299

273-
private void processFileInThread(File file, String fileEntryKey) {
274-
if (logger.isDebugEnabled()) {
275-
logger.debug("Parallel processing mode handling file: " + file.getName());
276-
}
277-
executorService.execute(new Runnable() {
278-
@Override
279-
public void run() {
280-
processSingleFile(file, fileEntryKey);
281-
}
282-
});
283-
}
284-
285300
protected abstract Message createMessage();
286301

287302
protected void processFile(File file) throws OpenAS2Exception {

changes.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
**IMPORTANT NOTE**: Please review upgrade notes in the RELEASE-NOTES.md if you are upgrading
22

3+
Version 4.6.3 - 2025-09-29
4+
5+
This is a bugfix release.
6+
1. Avoid concurrent processing error that occurs after files after sent as part of the cleanup process.
7+
38
Version 4.6.2 - 2025-09-27
49

510
This is a bugfix release.

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<modelVersion>4.0.0</modelVersion>
66
<groupId>net.sf.openas2</groupId>
77
<artifactId>OpenAS2</artifactId>
8-
<version>4.6.2</version>
8+
<version>4.6.3</version>
99
<name>OpenAS2</name>
1010
<packaging>pom</packaging>
1111

0 commit comments

Comments
 (0)