Skip to content

Commit

Permalink
Add file locking to prevent concurrency issues
Browse files Browse the repository at this point in the history
Added a file lock before performing a move or copy action in the FileDifference class to ensure that no concurrent modifications can happen during operation. With this, we can prevent potential data integrity issues when the file is accessed by another process at the same time. Two additional exceptions are added to handle the cases where the file is locked by another process or other unexpected situations occur.
  • Loading branch information
Rakambda committed Jul 19, 2023
1 parent 97387d3 commit e1c2703
Showing 1 changed file with 27 additions and 11 deletions.
38 changes: 27 additions & 11 deletions src/main/java/fr/rakambda/filesecure/files/FileDifference.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import java.nio.channels.FileChannel;
import java.nio.channels.OverlappingFileLockException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Objects;
import java.util.Optional;

/**
Expand Down Expand Up @@ -40,22 +44,34 @@ public void applyStrategy(@NotNull BackupStrategy backupStrategy){
var targetPath = desiredTarget.getTargetFolder().resolve(finalName);
log.info("{} file {} to {}", backupStrategy.name(), sourcePath, targetPath);
if(!Main.parameters.isDryRun()){
try{
switch(backupStrategy){
case MOVE -> {
Files.createDirectories(desiredTarget.getTargetFolder());
if(Files.isDirectory(desiredTarget.getTargetFolder())){
Files.move(sourcePath, targetPath);

try(var channel = FileChannel.open(sourcePath, StandardOpenOption.WRITE, StandardOpenOption.READ)){
var fileLock = channel.tryLock();
if(Objects.isNull(fileLock)){
log.warn("Failed to get lock for {}", sourcePath);
return;
}

try(fileLock){
switch(backupStrategy){
case MOVE -> {
Files.createDirectories(desiredTarget.getTargetFolder());
if(Files.isDirectory(desiredTarget.getTargetFolder())){
Files.move(sourcePath, targetPath);
}
}
}
case COPY -> {
Files.createDirectories(desiredTarget.getTargetFolder());
if(Files.isDirectory(desiredTarget.getTargetFolder())){
Files.copy(sourcePath, targetPath);
case COPY -> {
Files.createDirectories(desiredTarget.getTargetFolder());
if(Files.isDirectory(desiredTarget.getTargetFolder())){
Files.copy(sourcePath, targetPath);
}
}
}
}
}
catch(OverlappingFileLockException e){
log.warn("File {} is locked, skipping", sourcePath);
}
catch(Exception e){
log.warn("Error applying strategy {} on file {}", backupStrategy, sourcePath, e);
}
Expand Down

0 comments on commit e1c2703

Please sign in to comment.