mirror of https://github.com/micromata/borgbackup-butler.git

Kai Reinhard
06.50.2019 de2f2ca49cce4f4bf8fd0b86004bc29a9029db92
ConcurrentModificationException while multiple loading request of different repo archives.
2 files modified
52 ■■■■■ changed files
borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ArchiveFilelistCache.java 7 ●●●●● patch | view | raw | blame | history
borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ButlerCache.java 45 ●●●●● patch | view | raw | blame | history
borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ArchiveFilelistCache.java
@@ -53,7 +53,9 @@
            log.info("Saving archive content as file list: " + file.getAbsolutePath());
            try (ObjectOutputStream outputStream = new ObjectOutputStream(new BufferedOutputStream(new GzipCompressorOutputStream(new FileOutputStream(file))))) {
                outputStream.writeObject(filesystemItems.size());
                for (BorgFilesystemItem item : filesystemItems) {
                Iterator<BorgFilesystemItem> it = filesystemItems.iterator();
                while(it.hasNext()) {
                    BorgFilesystemItem item = it.next();
                    outputStream.writeObject(item);
                }
                outputStream.writeObject("EOF");
@@ -118,13 +120,13 @@
            return null;
        }
        log.info("Loading archive content as file list from: " + file.getAbsolutePath());
        List<BorgFilesystemItem> list = null;
        try {
            // Set last modified time of file:
            Files.setAttribute(file.toPath(), "lastModifiedTime", FileTime.fromMillis(System.currentTimeMillis()));
        } catch (IOException ex) {
            log.error("Can't set lastModifiedTime on file '" + file.getAbsolutePath() + "'. Pruning old cache files may not work.");
        }
        List<BorgFilesystemItem> list =  new ArrayList<>();
        try (ObjectInputStream inputStream = new ObjectInputStream(new BufferedInputStream(new GzipCompressorInputStream(new FileInputStream(file))))) {
            Object obj = inputStream.readObject();
            if (!(obj instanceof Integer)) {
@@ -132,7 +134,6 @@
                return null;
            }
            int size = (Integer) obj;
            list = new ArrayList<>();
            int fileNumber = -1;
            for (int i = 0; i < size; i++) {
                ++fileNumber;
borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ButlerCache.java
@@ -18,6 +18,7 @@
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
@@ -269,30 +270,34 @@
        if (archive == null || StringUtils.isBlank(archive.getName())) {
            return null;
        }
        List<BorgFilesystemItem> items = archiveFilelistCache.load(repoConfig, archive, filter);
        if (items == null && forceLoad) {
            List<BorgFilesystemItem> list = BorgCommands.listArchiveContent(repoConfig, archive);
            if (CollectionUtils.isNotEmpty(list)) {
                archiveFilelistCache.save(repoConfig, archive, list);
                items = new ArrayList<>();
                int fileNumber = -1;
                for (BorgFilesystemItem item : list) {
                    ++fileNumber;
                    item.setFileNumber(fileNumber);
                    if (filter == null || filter.matches(item)) {
                        items.add(item);
                        if (filter != null && filter.isFinished()) break;
        synchronized (archive) {
            List<BorgFilesystemItem> items = archiveFilelistCache.load(repoConfig, archive, filter);
            if (items == null && forceLoad) {
                List<BorgFilesystemItem> list = BorgCommands.listArchiveContent(repoConfig, archive);
                if (CollectionUtils.isNotEmpty(list)) {
                    archiveFilelistCache.save(repoConfig, archive, list);
                    items = new ArrayList<>();
                    int fileNumber = -1;
                    Iterator<BorgFilesystemItem> it = list.iterator(); // Don't use for-each (ConcurrentModificationException)
                    while (it.hasNext()) {
                        BorgFilesystemItem item = it.next();
                        ++fileNumber;
                        item.setFileNumber(fileNumber);
                        if (filter == null || filter.matches(item)) {
                            items.add(item);
                            if (filter != null && filter.isFinished()) break;
                        }
                    }
                    if (filter != null) {
                        items = filter.reduce(items);
                    }
                }
                if (filter != null) {
                    items = filter.reduce(items);
                }
            }
            if (items == null && forceLoad) {
                log.warn("Repo::archiv with name '" + archive.getBorgIdentifier() + "' not found.");
            }
            return items;
        }
        if (items == null && forceLoad) {
            log.warn("Repo::archiv with name '" + archive.getBorgIdentifier() + "' not found.");
        }
        return items;
    }
    public List<BorgFilesystemItem> getArchiveContent(File file) {