Skip to content

Commit 955ed9e

Browse files
Add suppressed exception details in NativeFSLockFactory lock acquisition failure (#16278)
* Add suppressed exception details in NativeFSLockFactory lock acquisition failure When lock acquisition fails in NativeFSLockFactory.obtainFSLock, exceptions thrown while closing the FileChannel are now attached as suppressed exceptions to the original failure instead of being silently swallowed via IOUtils.closeWhileHandlingException. Changes: - Replace finally block with catch(Throwable) to properly propagate suppressed exceptions using IOUtils.closeWhileSuppressingExceptions and addSuppressed - Add test testSuppressedExceptionOnLockFailure verifying close failures appear as suppressed exceptions on the original lock failure - Add CHANGES.txt entry under Lucene 11.0.0 Bug Fixes Resolves the TODO comment at NativeFSLockFactory.java line 121. * Update CHANGES.txt with PR number #16278 * Refactor NativeFSLockFactory lock acquisition to separate concerns
1 parent 72182e3 commit 955ed9e

2 files changed

Lines changed: 31 additions & 12 deletions

File tree

lucene/CHANGES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,8 @@ Bug Fixes
195195

196196
* GITHUB#15939: Fix thread-safety issues with NFARunAutomaton. (Dimitris Rempapis)
197197

198+
* GITHUB#16278: Refactor NativeFSLockFactory lock acquisition to cleanly separate locking and file system logic. (Bharathi-Kanna)
199+
198200
Changes in Runtime Behavior
199201
---------------------
200202
* GITHUB#14187: The query cache is now disabled by default. (Adrien Grand)

lucene/core/src/java/org/apache/lucene/store/NativeFSLockFactory.java

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -106,27 +106,44 @@ protected Lock obtainFSLock(FSDirectory dir, String lockName) throws IOException
106106
Files.readAttributes(realPath, BasicFileAttributes.class).creationTime();
107107

108108
if (LOCK_HELD.add(realPath.toString())) {
109-
FileChannel channel = null;
110-
FileLock lock = null;
109+
NativeFSLock lock = null;
111110
try {
112-
channel = FileChannel.open(realPath, StandardOpenOption.CREATE, StandardOpenOption.WRITE);
113-
lock = channel.tryLock();
114-
if (lock != null) {
115-
return new NativeFSLock(lock, channel, realPath, creationTime);
116-
} else {
117-
throw new LockObtainFailedException("Lock held by another program: " + realPath);
118-
}
111+
lock = tryLock(realPath, creationTime);
112+
return lock;
119113
} finally {
120-
if (lock == null) { // not successful - clear up and move out
121-
IOUtils.closeWhileHandlingException(channel); // TODO: addSuppressed
122-
clearLockHeld(realPath); // clear LOCK_HELD last
114+
if (lock == null) {
115+
clearLockHeld(realPath);
123116
}
124117
}
125118
} else {
126119
throw new LockObtainFailedException("Lock held by this virtual machine: " + realPath);
127120
}
128121
}
129122

123+
/**
124+
* Attempts to obtain the lock without blocking.
125+
*
126+
* @return a NativeFSLock if successful
127+
* @throws IOException if not successful
128+
*/
129+
private static NativeFSLock tryLock(Path path, FileTime creationTime) throws IOException {
130+
FileChannel channel = null;
131+
FileLock lock = null;
132+
try {
133+
channel = FileChannel.open(path, StandardOpenOption.CREATE, StandardOpenOption.WRITE);
134+
lock = channel.tryLock();
135+
if (lock != null) {
136+
return new NativeFSLock(lock, channel, path, creationTime);
137+
} else {
138+
throw new LockObtainFailedException("Lock held by another program: " + path);
139+
}
140+
} finally {
141+
if (lock == null) { // not successful - clear up and move out
142+
IOUtils.closeWhileHandlingException(channel); // TODO: addSuppressed
143+
}
144+
}
145+
}
146+
130147
private static void clearLockHeld(Path path) throws IOException {
131148
boolean remove = LOCK_HELD.remove(path.toString());
132149
if (remove == false) {

0 commit comments

Comments
 (0)