mirror of
https://github.com/booklore-app/booklore.git
synced 2026-02-18 00:17:53 +01:00
fix(library-service): prevent concurrent library scans with a tracking set (#2637)
Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
This commit is contained in:
@@ -38,6 +38,7 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@@ -45,6 +46,17 @@ import java.util.stream.Collectors;
|
||||
@AllArgsConstructor
|
||||
public class LibraryService {
|
||||
|
||||
private static final Set<Long> scanningLibraries = ConcurrentHashMap.newKeySet();
|
||||
|
||||
/**
|
||||
* Checks whether a library is currently being scanned.
|
||||
* Can be used by other components (e.g., file watcher) to avoid processing
|
||||
* files while a full scan is in progress.
|
||||
*/
|
||||
public static boolean isLibraryScanning(long libraryId) {
|
||||
return scanningLibraries.contains(libraryId);
|
||||
}
|
||||
|
||||
private final LibraryRepository libraryRepository;
|
||||
private final LibraryPathRepository libraryPathRepository;
|
||||
private final BookRepository bookRepository;
|
||||
@@ -125,10 +137,16 @@ public class LibraryService {
|
||||
|
||||
if (!newPaths.isEmpty()) {
|
||||
SecurityContextVirtualThread.runWithSecurityContext(() -> {
|
||||
if (!scanningLibraries.add(libraryId)) {
|
||||
log.warn("Library {} is already being scanned, skipping duplicate process request", libraryId);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
libraryProcessingService.processLibrary(libraryId);
|
||||
} catch (InvalidDataAccessApiUsageException e) {
|
||||
log.debug("InvalidDataAccessApiUsageException - Library id: {}", libraryId);
|
||||
} finally {
|
||||
scanningLibraries.remove(libraryId);
|
||||
}
|
||||
log.info("Parsing task completed!");
|
||||
});
|
||||
@@ -169,10 +187,16 @@ public class LibraryService {
|
||||
}
|
||||
|
||||
SecurityContextVirtualThread.runWithSecurityContext(() -> {
|
||||
if (!scanningLibraries.add(libraryId)) {
|
||||
log.warn("Library {} is already being scanned, skipping duplicate process request", libraryId);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
libraryProcessingService.processLibrary(libraryId);
|
||||
} catch (InvalidDataAccessApiUsageException e) {
|
||||
log.debug("InvalidDataAccessApiUsageException - Library id: {}", libraryId);
|
||||
} finally {
|
||||
scanningLibraries.remove(libraryId);
|
||||
}
|
||||
log.info("Parsing task completed!");
|
||||
});
|
||||
@@ -184,6 +208,10 @@ public class LibraryService {
|
||||
libraryRepository.findById(libraryId).orElseThrow(() -> ApiError.LIBRARY_NOT_FOUND.createException(libraryId));
|
||||
|
||||
SecurityContextVirtualThread.runWithSecurityContext(() -> {
|
||||
if (!scanningLibraries.add(libraryId)) {
|
||||
log.warn("Library {} is already being scanned, skipping duplicate rescan request", libraryId);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
RescanLibraryContext context = RescanLibraryContext.builder()
|
||||
.libraryId(libraryId)
|
||||
@@ -193,6 +221,8 @@ public class LibraryService {
|
||||
log.debug("InvalidDataAccessApiUsageException - Library id: {}", libraryId);
|
||||
} catch (IOException e) {
|
||||
log.error("Error while parsing library books", e);
|
||||
} finally {
|
||||
scanningLibraries.remove(libraryId);
|
||||
}
|
||||
log.info("Parsing task completed!");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user