From 9d4b365e63c74a6863d1c8d562c9e1487bda2c04 Mon Sep 17 00:00:00 2001 From: LoveIsGrief Date: Sun, 19 Jan 2020 21:43:03 +0100 Subject: [PATCH 01/16] Log the time it take to persist files and hashes --- .../main/groovy/com/muwire/core/files/PersisterService.groovy | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy b/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy index 217a9a40..e0cc84f3 100644 --- a/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy +++ b/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy @@ -155,6 +155,7 @@ class PersisterService extends Service { File tmp = File.createTempFile("muwire-files", "tmp") tmp.deleteOnExit() + def startTime = System.currentTimeMillis() tmp.withPrintWriter { writer -> sharedFiles.each { k, v -> def json = toJson(k,v) @@ -162,7 +163,10 @@ class PersisterService extends Service { writer.println json } } + log.info("Time(ms) to write tmp files.json: "+ (System.currentTimeMillis() - startTime)) + startTime = System.currentTimeMillis() Files.copy(tmp.toPath(), location.toPath(), StandardCopyOption.REPLACE_EXISTING) + log.info("Time(ms) to copy tmp files.json: "+ (System.currentTimeMillis() - startTime)) tmp.delete() } as Runnable) } From cd1757fac33ff4918af0b4e39b495055663c11a9 Mon Sep 17 00:00:00 2001 From: LoveIsGrief Date: Sun, 19 Jan 2020 21:46:47 +0100 Subject: [PATCH 02/16] Use Java 11 Java9 isn't available on Ubuntu anymore, which would make development harder --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 8770cc3f..19520b19 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ FROM jlesage/baseimage-gui:alpine-3.10-glibc ARG DOCKER_IMAGE_VERSION=unknown # JDK version -ARG JDK=9 +ARG JDK=11 # Important directories ARG TMP_DIR=/muwire-tmp From 043028c296a3dd14d3f4457f949057b726d5a0bd Mon Sep 17 00:00:00 2001 From: LoveIsGrief Date: Tue, 21 Jan 2020 23:34:33 +0100 Subject: [PATCH 03/16] Introduce PersisterFolderService to replace PersisterService An attempt at automatically migrate from PersisterService was made, but the events aren't triggered in the right order. We need to make sure that we don't trigger the "AllFilesLoadedEvent" before the migration is done --- .../main/groovy/com/muwire/core/Core.groovy | 16 +- .../core/files/BasePersisterService.groovy | 109 +++++++++++++ .../muwire/core/files/FileLoadedEvent.groovy | 1 + .../core/files/PersisterFolderService.groovy | 144 ++++++++++++++++++ .../muwire/core/files/PersisterService.groovy | 143 +---------------- .../main/java/com/muwire/core/SharedFile.java | 12 ++ .../com/muwire/gui/MainFrameController.groovy | 11 +- 7 files changed, 286 insertions(+), 150 deletions(-) create mode 100644 core/src/main/groovy/com/muwire/core/files/BasePersisterService.groovy create mode 100644 core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy diff --git a/core/src/main/groovy/com/muwire/core/Core.groovy b/core/src/main/groovy/com/muwire/core/Core.groovy index d4481089..0e930e14 100644 --- a/core/src/main/groovy/com/muwire/core/Core.groovy +++ b/core/src/main/groovy/com/muwire/core/Core.groovy @@ -1,5 +1,7 @@ package com.muwire.core +import com.muwire.core.files.PersisterFolderService + import java.nio.charset.StandardCharsets import java.util.concurrent.atomic.AtomicBoolean @@ -31,7 +33,6 @@ import com.muwire.core.filecert.UIFetchCertificatesEvent import com.muwire.core.filecert.UIImportCertificateEvent import com.muwire.core.files.FileDownloadedEvent import com.muwire.core.files.FileHashedEvent -import com.muwire.core.files.FileHashingEvent import com.muwire.core.files.FileHasher import com.muwire.core.files.FileLoadedEvent import com.muwire.core.files.FileManager @@ -74,10 +75,8 @@ import net.i2p.client.I2PClientFactory import net.i2p.client.I2PSession import net.i2p.client.streaming.I2PSocketManager import net.i2p.client.streaming.I2PSocketManagerFactory -import net.i2p.client.streaming.I2PSocketOptions import net.i2p.client.streaming.I2PSocketManager.DisconnectListener import net.i2p.crypto.DSAEngine -import net.i2p.crypto.SigType import net.i2p.data.Destination import net.i2p.data.PrivateKey import net.i2p.data.Signature @@ -100,6 +99,7 @@ public class Core { final TrustService trustService final TrustSubscriber trustSubscriber private final PersisterService persisterService + private final PersisterFolderService persisterFolderService private final HostCache hostCache private final ConnectionManager connectionManager private final CacheClient cacheClient @@ -259,7 +259,13 @@ public class Core { log.info "initializing persistence service" persisterService = new PersisterService(new File(home, "files.json"), eventBus, 60000, fileManager) eventBus.register(UILoadedEvent.class, persisterService) - eventBus.register(UIPersistFilesEvent.class, persisterService) + + log.info "initializing folder persistence service" + persisterFolderService = new PersisterFolderService(new File(home, "files"), eventBus) + eventBus.register(UILoadedEvent.class, persisterFolderService) + eventBus.register(UIPersistFilesEvent.class, persisterFolderService) + eventBus.register(FileHashedEvent.class, persisterFolderService) + eventBus.register(FileUnsharedEvent.class, persisterFolderService) log.info("initializing host cache") File hostStorage = new File(home, "hosts.json") @@ -398,6 +404,8 @@ public class Core { trustService.stop() log.info("shutting down persister service") persisterService.stop() + log.info("shutting down persisterFolder service") + persisterFolderService.stop() log.info("shutting down download manager") downloadManager.shutdown() log.info("shutting down connection acceptor") diff --git a/core/src/main/groovy/com/muwire/core/files/BasePersisterService.groovy b/core/src/main/groovy/com/muwire/core/files/BasePersisterService.groovy new file mode 100644 index 00000000..68641142 --- /dev/null +++ b/core/src/main/groovy/com/muwire/core/files/BasePersisterService.groovy @@ -0,0 +1,109 @@ +package com.muwire.core.files + +import com.muwire.core.DownloadedFile +import com.muwire.core.InfoHash +import com.muwire.core.Persona +import com.muwire.core.Service +import com.muwire.core.SharedFile +import com.muwire.core.util.DataUtil +import net.i2p.data.Base64 +import net.i2p.data.Destination + +import java.util.stream.Collectors + +abstract class BasePersisterService extends Service{ + + protected static FileLoadedEvent fromJson(def json) { + if (json.file == null || json.length == null || json.infoHash == null || json.hashList == null) + throw new IllegalArgumentException() + if (!(json.hashList instanceof List)) + throw new IllegalArgumentException() + + def file = new File(DataUtil.readi18nString(Base64.decode(json.file))) + file = file.getCanonicalFile() + if (!file.exists() || file.isDirectory()) + return null + long length = Long.valueOf(json.length) + if (length != file.length()) + return null + + List hashList = (List) json.hashList + ByteArrayOutputStream baos = new ByteArrayOutputStream() + hashList.each { + byte [] hash = Base64.decode it.toString() + if (hash == null) + throw new IllegalArgumentException() + baos.write hash + } + byte[] hashListBytes = baos.toByteArray() + + InfoHash ih = InfoHash.fromHashList(hashListBytes) + byte [] root = Base64.decode(json.infoHash.toString()) + if (root == null) + throw new IllegalArgumentException() + if (!Arrays.equals(root, ih.getRoot())) + return null + + int pieceSize = 0 + if (json.pieceSize != null) + pieceSize = json.pieceSize + + if (json.sources != null) { + List sources = (List)json.sources + Set sourceSet = sources.stream().map({ d -> new Destination(d.toString())}).collect Collectors.toSet() + DownloadedFile df = new DownloadedFile(file, ih, pieceSize, sourceSet) + df.setComment(json.comment) + return new FileLoadedEvent(loadedFile : df, sourceClass : this.class) + } + + + SharedFile sf = new SharedFile(file, ih, pieceSize) + sf.setComment(json.comment) + if (json.downloaders != null) + sf.getDownloaders().addAll(json.downloaders) + if (json.searchers != null) { + json.searchers.each { + Persona searcher = null + if (it.searcher != null) + searcher = new Persona(new ByteArrayInputStream(Base64.decode(it.searcher))) + long timestamp = it.timestamp + String query = it.query + sf.hit(searcher, timestamp, query) + } + } + return new FileLoadedEvent(loadedFile: sf) + + } + + protected static toJson(SharedFile sf) { + def json = [:] + json.file = sf.getB64EncodedFileName() + json.length = sf.getCachedLength() + InfoHash ih = sf.getInfoHash() + json.infoHash = sf.getB64EncodedHashRoot() + json.pieceSize = sf.getPieceSize() + json.hashList = sf.getB64EncodedHashList() + json.comment = sf.getComment() + json.hits = sf.getHits() + json.downloaders = sf.getDownloaders() + + if (!sf.searches.isEmpty()) { + Set searchers = new HashSet<>() + sf.searches.each { + def search = [:] + if (it.searcher != null) + search.searcher = it.searcher.toBase64() + search.timestamp = it.timestamp + search.query = it.query + searchers.add(search) + } + json.searchers = searchers + } + + if (sf instanceof DownloadedFile) { + json.sources = sf.sources.stream().map( {d -> d.toBase64()}).collect(Collectors.toList()) + } + + json + } +} diff --git a/core/src/main/groovy/com/muwire/core/files/FileLoadedEvent.groovy b/core/src/main/groovy/com/muwire/core/files/FileLoadedEvent.groovy index 5551ebed..3ca1d5f7 100644 --- a/core/src/main/groovy/com/muwire/core/files/FileLoadedEvent.groovy +++ b/core/src/main/groovy/com/muwire/core/files/FileLoadedEvent.groovy @@ -6,4 +6,5 @@ import com.muwire.core.SharedFile class FileLoadedEvent extends Event { SharedFile loadedFile + Class sourceClass } diff --git a/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy b/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy new file mode 100644 index 00000000..a4534f55 --- /dev/null +++ b/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy @@ -0,0 +1,144 @@ +package com.muwire.core.files + +import com.muwire.core.* +import groovy.json.JsonOutput +import groovy.json.JsonSlurper +import groovy.util.logging.Log + +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths +import java.util.concurrent.ExecutorService +import java.util.concurrent.Executors +import java.util.concurrent.ThreadFactory +import java.util.logging.Level + +/** + * A persister that stores information about the files shared using + * individual JSON files in directories. + * + * The absolute path's 32bit hash to the shared file is used + * to build the directory and filename. + * @see PersisterFolderService#getJsonPath + */ +@Log +class PersisterFolderService extends BasePersisterService { + + final static int CUT_LENGTH = 6 + + final File location + final EventBus listener + final int interval + final Timer timer + final ExecutorService persisterExecutor = Executors.newSingleThreadExecutor({ r -> + new Thread(r, "file persister") + } as ThreadFactory) + + PersisterFolderService(File location, EventBus listener) { + this.location = location + this.listener = listener + this.interval = interval + timer = new Timer("file-folder persister timer", true) + } + + void stop() { + timer.cancel() + persisterExecutor.shutdown() + } + + void onUILoadedEvent(UILoadedEvent e) { + timer.schedule({ load() } as TimerTask, 1) + } + + void onUIPersistFilesEvent(UIPersistFilesEvent e) { + persistFiles() + } + + void onFileHashedEvent(FileHashedEvent hashedEvent) { + persistFile(hashedEvent.sharedFile) + } + /** + * Get rid of the json of unshared files + * @param unsharedEvent + */ + void onFileUnsharedEvent(FileUnsharedEvent unsharedEvent) { + def jsonPath = getJsonPath(unsharedEvent.unsharedFile) + def jsonFile = jsonPath.toFile() + if(jsonFile.isFile()){ + jsonFile.delete() + } + } + void onFileLoadedEvent(FileLoadedEvent loadedEvent) { + if(loadedEvent.sourceClass == PersisterService){ + log.info("Migrating persisted file from PersisterService") + persistFile(loadedEvent.loadedFile) + } + } + + void load() { + Thread.currentThread().setPriority(Thread.MIN_PRIORITY) + + if (location.exists() && location.isDirectory()) { + try { + _load() + } + catch (IllegalArgumentException e) { + log.log(Level.WARNING, "couldn't load files", e) + } + } else { + location.mkdirs() + listener.publish(new AllFilesLoadedEvent()) + } + loaded = true + } + + /** + * Loads every JSON into memory + * + * TODO: Decide if this is a good idea + * The more shared files, the more we'll load in memory. + * It might not be necessary + */ + private void _load() { + int loaded = 0 + def slurper = new JsonSlurper() + Files.walk(location.toPath()) + .filter({ it.fileName.endsWith(".json") }) + .forEach({ + def parsed = slurper.parse it.toFile() + def event = fromJson parsed + if (event == null) return + + log.fine("loaded file $event.loadedFile.file") + listener.publish event + loaded++ + if (loaded % 10 == 0) + Thread.sleep(20) + + }) + listener.publish(new AllFilesLoadedEvent()) + } + + private void persistFile(SharedFile sf) { + persisterExecutor.submit({ + def jsonPath = getJsonPath(sf) + + def startTime = System.currentTimeMillis() + jsonPath.parent.toFile().mkdir() + jsonPath.toFile().withPrintWriter { writer -> + def json = toJson sf + json = JsonOutput.toJson(json) + writer.println json + } + log.fine("Time(ms) to write json: " + (System.currentTimeMillis() - startTime)) + } as Runnable) + } + private Path getJsonPath(SharedFile sf){ + def pathHash = sf.getB64PathHash() + return Paths.get( + location.getAbsolutePath(), + pathHash.substring(0, CUT_LENGTH), + pathHash.substring(CUT_LENGTH) + ".json" + ) + } +} diff --git a/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy b/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy index e0cc84f3..742de69f 100644 --- a/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy +++ b/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy @@ -1,31 +1,18 @@ package com.muwire.core.files -import java.nio.file.CopyOption -import java.nio.file.Files -import java.nio.file.StandardCopyOption + import java.util.concurrent.ExecutorService import java.util.concurrent.Executors import java.util.concurrent.ThreadFactory import java.util.logging.Level -import java.util.stream.Collectors -import com.muwire.core.DownloadedFile import com.muwire.core.EventBus -import com.muwire.core.InfoHash -import com.muwire.core.Persona -import com.muwire.core.Service -import com.muwire.core.SharedFile import com.muwire.core.UILoadedEvent -import com.muwire.core.util.DataUtil - -import groovy.json.JsonOutput import groovy.json.JsonSlurper import groovy.util.logging.Log -import net.i2p.data.Base64 -import net.i2p.data.Destination @Log -class PersisterService extends Service { +class PersisterService extends BasePersisterService { final File location final EventBus listener @@ -46,15 +33,12 @@ class PersisterService extends Service { void stop() { timer.cancel() + persisterExecutor.shutdown() } void onUILoadedEvent(UILoadedEvent e) { timer.schedule({load()} as TimerTask, 1) } - - void onUIPersistFilesEvent(UIPersistFilesEvent e) { - persistFiles() - } void load() { Thread.currentThread().setPriority(Thread.MIN_PRIORITY) @@ -76,130 +60,17 @@ class PersisterService extends Service { } } } + // TODO: should PersisterFolderService be the one doing this? listener.publish(new AllFilesLoadedEvent()) - } catch (IllegalArgumentException|NumberFormatException e) { + } catch (IllegalArgumentException e) { log.log(Level.WARNING, "couldn't load files",e) } } else { + // TODO: should PersisterFolderService be the one doing this? listener.publish(new AllFilesLoadedEvent()) } - timer.schedule({persistFiles()} as TimerTask, 1000, interval) + // TODO: Get rid of the files.json loaded = true } - private static FileLoadedEvent fromJson(def json) { - if (json.file == null || json.length == null || json.infoHash == null || json.hashList == null) - throw new IllegalArgumentException() - if (!(json.hashList instanceof List)) - throw new IllegalArgumentException() - - def file = new File(DataUtil.readi18nString(Base64.decode(json.file))) - file = file.getCanonicalFile() - if (!file.exists() || file.isDirectory()) - return null - long length = Long.valueOf(json.length) - if (length != file.length()) - return null - - List hashList = (List) json.hashList - ByteArrayOutputStream baos = new ByteArrayOutputStream() - hashList.each { - byte [] hash = Base64.decode it.toString() - if (hash == null) - throw new IllegalArgumentException() - baos.write hash - } - byte[] hashListBytes = baos.toByteArray() - - InfoHash ih = InfoHash.fromHashList(hashListBytes) - byte [] root = Base64.decode(json.infoHash.toString()) - if (root == null) - throw new IllegalArgumentException() - if (!Arrays.equals(root, ih.getRoot())) - return null - - int pieceSize = 0 - if (json.pieceSize != null) - pieceSize = json.pieceSize - - if (json.sources != null) { - List sources = (List)json.sources - Set sourceSet = sources.stream().map({d -> new Destination(d.toString())}).collect Collectors.toSet() - DownloadedFile df = new DownloadedFile(file, ih, pieceSize, sourceSet) - df.setComment(json.comment) - return new FileLoadedEvent(loadedFile : df) - } - - - SharedFile sf = new SharedFile(file, ih, pieceSize) - sf.setComment(json.comment) - if (json.downloaders != null) - sf.getDownloaders().addAll(json.downloaders) - if (json.searchers != null) { - json.searchers.each { - Persona searcher = null - if (it.searcher != null) - searcher = new Persona(new ByteArrayInputStream(Base64.decode(it.searcher))) - long timestamp = it.timestamp - String query = it.query - sf.hit(searcher, timestamp, query) - } - } - return new FileLoadedEvent(loadedFile: sf) - - } - - private void persistFiles() { - persisterExecutor.submit( { - def sharedFiles = fileManager.getSharedFiles() - - File tmp = File.createTempFile("muwire-files", "tmp") - tmp.deleteOnExit() - def startTime = System.currentTimeMillis() - tmp.withPrintWriter { writer -> - sharedFiles.each { k, v -> - def json = toJson(k,v) - json = JsonOutput.toJson(json) - writer.println json - } - } - log.info("Time(ms) to write tmp files.json: "+ (System.currentTimeMillis() - startTime)) - startTime = System.currentTimeMillis() - Files.copy(tmp.toPath(), location.toPath(), StandardCopyOption.REPLACE_EXISTING) - log.info("Time(ms) to copy tmp files.json: "+ (System.currentTimeMillis() - startTime)) - tmp.delete() - } as Runnable) - } - - private def toJson(File f, SharedFile sf) { - def json = [:] - json.file = sf.getB64EncodedFileName() - json.length = sf.getCachedLength() - InfoHash ih = sf.getInfoHash() - json.infoHash = sf.getB64EncodedHashRoot() - json.pieceSize = sf.getPieceSize() - json.hashList = sf.getB64EncodedHashList() - json.comment = sf.getComment() - json.hits = sf.getHits() - json.downloaders = sf.getDownloaders() - - if (!sf.searches.isEmpty()) { - Set searchers = new HashSet<>() - sf.searches.each { - def search = [:] - if (it.searcher != null) - search.searcher = it.searcher.toBase64() - search.timestamp = it.timestamp - search.query = it.query - searchers.add(search) - } - json.searchers = searchers - } - - if (sf instanceof DownloadedFile) { - json.sources = sf.sources.stream().map( {d -> d.toBase64()}).collect(Collectors.toList()) - } - - json - } } diff --git a/core/src/main/java/com/muwire/core/SharedFile.java b/core/src/main/java/com/muwire/core/SharedFile.java index f3bc296a..c79ef9d5 100644 --- a/core/src/main/java/com/muwire/core/SharedFile.java +++ b/core/src/main/java/com/muwire/core/SharedFile.java @@ -2,6 +2,8 @@ package com.muwire.core; import java.io.File; import java.io.IOException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -52,6 +54,16 @@ public class SharedFile { return file; } + public byte[] getPathHash() throws NoSuchAlgorithmException { + var digester = MessageDigest.getInstance("SHA-256"); + digester.update(file.getAbsolutePath().getBytes()); + return digester.digest(); + } + + public String getB64PathHash() throws NoSuchAlgorithmException { + return Base64.encode(getPathHash()); + } + public InfoHash getInfoHash() { return infoHash; } diff --git a/gui/griffon-app/controllers/com/muwire/gui/MainFrameController.groovy b/gui/griffon-app/controllers/com/muwire/gui/MainFrameController.groovy index 3a184b61..298e9b43 100644 --- a/gui/griffon-app/controllers/com/muwire/gui/MainFrameController.groovy +++ b/gui/griffon-app/controllers/com/muwire/gui/MainFrameController.groovy @@ -3,15 +3,11 @@ package com.muwire.gui import griffon.core.GriffonApplication import griffon.core.artifact.GriffonController import griffon.core.controller.ControllerAction -import griffon.core.mvc.MVCGroup -import griffon.core.mvc.MVCGroupConfiguration import griffon.inject.MVCMember import griffon.metadata.ArtifactProviderFor -import groovy.json.StringEscapeUtils import net.i2p.crypto.DSAEngine import net.i2p.data.Base64 import net.i2p.data.Signature -import net.i2p.data.SigningPrivateKey import java.awt.Desktop import java.awt.Toolkit @@ -30,15 +26,11 @@ import com.muwire.core.Persona import com.muwire.core.SharedFile import com.muwire.core.SplitPattern import com.muwire.core.download.Downloader -import com.muwire.core.download.DownloadStartedEvent import com.muwire.core.download.UIDownloadCancelledEvent -import com.muwire.core.download.UIDownloadEvent import com.muwire.core.download.UIDownloadPausedEvent import com.muwire.core.download.UIDownloadResumedEvent import com.muwire.core.filecert.UICreateCertificateEvent -import com.muwire.core.files.DirectoryUnsharedEvent import com.muwire.core.files.FileUnsharedEvent -import com.muwire.core.files.UIPersistFilesEvent import com.muwire.core.search.QueryEvent import com.muwire.core.search.SearchEvent import com.muwire.core.trust.RemoteTrustList @@ -371,7 +363,6 @@ class MainFrameController { sf.each { core.eventBus.publish(new FileUnsharedEvent(unsharedFile : it)) } - core.eventBus.publish(new UIPersistFilesEvent()) } @ControllerAction @@ -534,4 +525,4 @@ class MainFrameController { core = e.getNewValue() }) } -} \ No newline at end of file +} From 598ab90f63097de084c9fb0c232e28ae7c3aec71 Mon Sep 17 00:00:00 2001 From: LoveIsGrief Date: Wed, 22 Jan 2020 12:36:34 +0100 Subject: [PATCH 04/16] Clear up the event path when starting up the old and new persisters The new persister won't load anything until the old one has finished --- core/src/main/groovy/com/muwire/core/Core.groovy | 3 ++- .../com/muwire/core/files/PersisterDoneEvent.groovy | 12 ++++++++++++ .../muwire/core/files/PersisterFolderService.groovy | 6 ++++-- .../com/muwire/core/files/PersisterService.groovy | 11 ++++++----- 4 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 core/src/main/groovy/com/muwire/core/files/PersisterDoneEvent.groovy diff --git a/core/src/main/groovy/com/muwire/core/Core.groovy b/core/src/main/groovy/com/muwire/core/Core.groovy index 0e930e14..97dbada5 100644 --- a/core/src/main/groovy/com/muwire/core/Core.groovy +++ b/core/src/main/groovy/com/muwire/core/Core.groovy @@ -1,5 +1,6 @@ package com.muwire.core +import com.muwire.core.files.PersisterDoneEvent import com.muwire.core.files.PersisterFolderService import java.nio.charset.StandardCharsets @@ -262,7 +263,7 @@ public class Core { log.info "initializing folder persistence service" persisterFolderService = new PersisterFolderService(new File(home, "files"), eventBus) - eventBus.register(UILoadedEvent.class, persisterFolderService) + eventBus.register(PersisterDoneEvent.class, persisterFolderService) eventBus.register(UIPersistFilesEvent.class, persisterFolderService) eventBus.register(FileHashedEvent.class, persisterFolderService) eventBus.register(FileUnsharedEvent.class, persisterFolderService) diff --git a/core/src/main/groovy/com/muwire/core/files/PersisterDoneEvent.groovy b/core/src/main/groovy/com/muwire/core/files/PersisterDoneEvent.groovy new file mode 100644 index 00000000..5d12220c --- /dev/null +++ b/core/src/main/groovy/com/muwire/core/files/PersisterDoneEvent.groovy @@ -0,0 +1,12 @@ +package com.muwire.core.files + +import com.muwire.core.Event + +/** + * Should be triggered by the old PersisterService + * once it has finished reading the old file + * + * @see PersisterService + */ +class PersisterDoneEvent extends Event{ +} diff --git a/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy b/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy index a4534f55..642f8166 100644 --- a/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy +++ b/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy @@ -19,6 +19,8 @@ import java.util.logging.Level * * The absolute path's 32bit hash to the shared file is used * to build the directory and filename. + * + * This persister only starts working once the old persister has finished loading * @see PersisterFolderService#getJsonPath */ @Log @@ -46,8 +48,8 @@ class PersisterFolderService extends BasePersisterService { persisterExecutor.shutdown() } - void onUILoadedEvent(UILoadedEvent e) { - timer.schedule({ load() } as TimerTask, 1) + void onPersisterDoneEvent(PersisterDoneEvent persisterDoneEvent) { + load() } void onUIPersistFilesEvent(UIPersistFilesEvent e) { diff --git a/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy b/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy index 742de69f..31b3b610 100644 --- a/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy +++ b/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy @@ -60,16 +60,17 @@ class PersisterService extends BasePersisterService { } } } - // TODO: should PersisterFolderService be the one doing this? - listener.publish(new AllFilesLoadedEvent()) + // Backup the old hashes + location.renameTo( + new File(location.absolutePath + ".bak") + ) + listener.publish(new PersisterDoneEvent()) } catch (IllegalArgumentException e) { log.log(Level.WARNING, "couldn't load files",e) } } else { - // TODO: should PersisterFolderService be the one doing this? - listener.publish(new AllFilesLoadedEvent()) + listener.publish(new PersisterDoneEvent()) } - // TODO: Get rid of the files.json loaded = true } From 7446fc949a23ca7357de864b091fb8dfcf9e2b83 Mon Sep 17 00:00:00 2001 From: LoveIsGrief Date: Wed, 22 Jan 2020 13:00:55 +0100 Subject: [PATCH 05/16] Remove UIPersistFilesEvent Hashing is done per file now and those are triggered by individual events --- .../src/main/groovy/com/muwire/clilanterna/FilesView.groovy | 2 -- core/src/main/groovy/com/muwire/core/Core.groovy | 3 +-- .../com/muwire/core/files/PersisterFolderService.groovy | 4 ---- .../groovy/com/muwire/core/files/UIPersistFilesEvent.groovy | 6 ------ 4 files changed, 1 insertion(+), 14 deletions(-) delete mode 100644 core/src/main/groovy/com/muwire/core/files/UIPersistFilesEvent.groovy diff --git a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/FilesView.groovy b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/FilesView.groovy index f7cf6e78..2d7aba3a 100644 --- a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/FilesView.groovy +++ b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/FilesView.groovy @@ -21,7 +21,6 @@ import com.muwire.core.filecert.UICreateCertificateEvent import com.muwire.core.files.DirectoryUnsharedEvent import com.muwire.core.files.FileSharedEvent import com.muwire.core.files.FileUnsharedEvent -import com.muwire.core.files.UIPersistFilesEvent class FilesView extends BasicWindow { private final FilesModel model @@ -84,7 +83,6 @@ class FilesView extends BasicWindow { Button unshareButton = new Button("Unshare", { core.eventBus.publish(new FileUnsharedEvent(unsharedFile : sf)) - core.eventBus.publish(new UIPersistFilesEvent()) MessageDialog.showMessageDialog(textGUI, "File Unshared", "Unshared "+sf.getFile().getName(), MessageDialogButton.OK) } ) Button addCommentButton = new Button("Add Comment", { diff --git a/core/src/main/groovy/com/muwire/core/Core.groovy b/core/src/main/groovy/com/muwire/core/Core.groovy index 97dbada5..cd1148bd 100644 --- a/core/src/main/groovy/com/muwire/core/Core.groovy +++ b/core/src/main/groovy/com/muwire/core/Core.groovy @@ -43,7 +43,7 @@ import com.muwire.core.files.HasherService import com.muwire.core.files.PersisterService import com.muwire.core.files.SideCarFileEvent import com.muwire.core.files.UICommentEvent -import com.muwire.core.files.UIPersistFilesEvent + import com.muwire.core.files.AllFilesLoadedEvent import com.muwire.core.files.DirectoryUnsharedEvent import com.muwire.core.files.DirectoryWatchedEvent @@ -264,7 +264,6 @@ public class Core { log.info "initializing folder persistence service" persisterFolderService = new PersisterFolderService(new File(home, "files"), eventBus) eventBus.register(PersisterDoneEvent.class, persisterFolderService) - eventBus.register(UIPersistFilesEvent.class, persisterFolderService) eventBus.register(FileHashedEvent.class, persisterFolderService) eventBus.register(FileUnsharedEvent.class, persisterFolderService) diff --git a/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy b/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy index 642f8166..9658b10e 100644 --- a/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy +++ b/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy @@ -52,10 +52,6 @@ class PersisterFolderService extends BasePersisterService { load() } - void onUIPersistFilesEvent(UIPersistFilesEvent e) { - persistFiles() - } - void onFileHashedEvent(FileHashedEvent hashedEvent) { persistFile(hashedEvent.sharedFile) } diff --git a/core/src/main/groovy/com/muwire/core/files/UIPersistFilesEvent.groovy b/core/src/main/groovy/com/muwire/core/files/UIPersistFilesEvent.groovy deleted file mode 100644 index 6cfbc76c..00000000 --- a/core/src/main/groovy/com/muwire/core/files/UIPersistFilesEvent.groovy +++ /dev/null @@ -1,6 +0,0 @@ -package com.muwire.core.files - -import com.muwire.core.Event - -class UIPersistFilesEvent extends Event { -} From 7cee8a28ba7c972e510aa00dc8f6cb7c999cc2fb Mon Sep 17 00:00:00 2001 From: LoveIsGrief Date: Wed, 22 Jan 2020 15:07:00 +0100 Subject: [PATCH 06/16] FileLoadedEvent should include class when coming from old persister Otherwise the new PersisterFolderService won't migrate --- .../groovy/com/muwire/core/files/BasePersisterService.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/groovy/com/muwire/core/files/BasePersisterService.groovy b/core/src/main/groovy/com/muwire/core/files/BasePersisterService.groovy index 68641142..65d601f7 100644 --- a/core/src/main/groovy/com/muwire/core/files/BasePersisterService.groovy +++ b/core/src/main/groovy/com/muwire/core/files/BasePersisterService.groovy @@ -71,7 +71,7 @@ abstract class BasePersisterService extends Service{ sf.hit(searcher, timestamp, query) } } - return new FileLoadedEvent(loadedFile: sf) + return new FileLoadedEvent(loadedFile: sf, sourceClass: this.class) } From dcd233b7ad790993b05896abc8868083b18252f9 Mon Sep 17 00:00:00 2001 From: LoveIsGrief Date: Wed, 22 Jan 2020 15:12:01 +0100 Subject: [PATCH 07/16] Reduce log levels in Connection Too verbose --- .../main/groovy/com/muwire/core/connection/Connection.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/groovy/com/muwire/core/connection/Connection.groovy b/core/src/main/groovy/com/muwire/core/connection/Connection.groovy index 39b9ab82..69e525f8 100644 --- a/core/src/main/groovy/com/muwire/core/connection/Connection.groovy +++ b/core/src/main/groovy/com/muwire/core/connection/Connection.groovy @@ -88,11 +88,11 @@ abstract class Connection implements Closeable { log.log(Level.WARNING, "$name already closed", new Exception() ) return } - log.info("closing $name") + log.fine("closing $name") reader.interrupt() writer.interrupt() endpoint.close() - log.info("closed $name") + log.fine("closed $name") eventBus.publish(new DisconnectionEvent(destination: endpoint.destination)) } From 5c18b4a1411b7077cd2aaa85f7aa496084139399 Mon Sep 17 00:00:00 2001 From: LoveIsGrief Date: Wed, 22 Jan 2020 15:12:22 +0100 Subject: [PATCH 08/16] Add more logs PersisterFolderService --- .../groovy/com/muwire/core/files/PersisterFolderService.groovy | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy b/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy index 9658b10e..45f10b30 100644 --- a/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy +++ b/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy @@ -49,6 +49,7 @@ class PersisterFolderService extends BasePersisterService { } void onPersisterDoneEvent(PersisterDoneEvent persisterDoneEvent) { + log.info("Old persister done") load() } @@ -74,6 +75,7 @@ class PersisterFolderService extends BasePersisterService { } void load() { + log.fine("Loading...") Thread.currentThread().setPriority(Thread.MIN_PRIORITY) if (location.exists() && location.isDirectory()) { From e27704c1af3d9f7715d8a39af6a4ffc9e0c955d7 Mon Sep 17 00:00:00 2001 From: LoveIsGrief Date: Wed, 22 Jan 2020 20:59:05 +0100 Subject: [PATCH 09/16] Make sure migration from PersisterService works this.getClass() and this.class kept resolving to Class. Using a string is much simpler mkdirs() is also necessary because the directory structure doesn't exist when persistFile is called the first time --- core/src/main/groovy/com/muwire/core/Core.groovy | 1 + .../com/muwire/core/files/BasePersisterService.groovy | 4 ++-- .../groovy/com/muwire/core/files/FileLoadedEvent.groovy | 2 +- .../com/muwire/core/files/PersisterFolderService.groovy | 7 ++++--- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/core/src/main/groovy/com/muwire/core/Core.groovy b/core/src/main/groovy/com/muwire/core/Core.groovy index cd1148bd..8f770081 100644 --- a/core/src/main/groovy/com/muwire/core/Core.groovy +++ b/core/src/main/groovy/com/muwire/core/Core.groovy @@ -264,6 +264,7 @@ public class Core { log.info "initializing folder persistence service" persisterFolderService = new PersisterFolderService(new File(home, "files"), eventBus) eventBus.register(PersisterDoneEvent.class, persisterFolderService) + eventBus.register(FileLoadedEvent.class, persisterFolderService) eventBus.register(FileHashedEvent.class, persisterFolderService) eventBus.register(FileUnsharedEvent.class, persisterFolderService) diff --git a/core/src/main/groovy/com/muwire/core/files/BasePersisterService.groovy b/core/src/main/groovy/com/muwire/core/files/BasePersisterService.groovy index 65d601f7..b6d20163 100644 --- a/core/src/main/groovy/com/muwire/core/files/BasePersisterService.groovy +++ b/core/src/main/groovy/com/muwire/core/files/BasePersisterService.groovy @@ -53,7 +53,7 @@ abstract class BasePersisterService extends Service{ Set sourceSet = sources.stream().map({ d -> new Destination(d.toString())}).collect Collectors.toSet() DownloadedFile df = new DownloadedFile(file, ih, pieceSize, sourceSet) df.setComment(json.comment) - return new FileLoadedEvent(loadedFile : df, sourceClass : this.class) + return new FileLoadedEvent(loadedFile : df, source : "PersisterService") } @@ -71,7 +71,7 @@ abstract class BasePersisterService extends Service{ sf.hit(searcher, timestamp, query) } } - return new FileLoadedEvent(loadedFile: sf, sourceClass: this.class) + return new FileLoadedEvent(loadedFile: sf, source : "PersisterService") } diff --git a/core/src/main/groovy/com/muwire/core/files/FileLoadedEvent.groovy b/core/src/main/groovy/com/muwire/core/files/FileLoadedEvent.groovy index 3ca1d5f7..0dc31f0c 100644 --- a/core/src/main/groovy/com/muwire/core/files/FileLoadedEvent.groovy +++ b/core/src/main/groovy/com/muwire/core/files/FileLoadedEvent.groovy @@ -6,5 +6,5 @@ import com.muwire.core.SharedFile class FileLoadedEvent extends Event { SharedFile loadedFile - Class sourceClass + String source } diff --git a/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy b/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy index 45f10b30..9e718532 100644 --- a/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy +++ b/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy @@ -68,8 +68,9 @@ class PersisterFolderService extends BasePersisterService { } } void onFileLoadedEvent(FileLoadedEvent loadedEvent) { - if(loadedEvent.sourceClass == PersisterService){ - log.info("Migrating persisted file from PersisterService") + if(loadedEvent.source == "PersisterService"){ + log.info("Migrating persisted file from PersisterService: " + + loadedEvent.loadedFile.file.absolutePath.toString()) persistFile(loadedEvent.loadedFile) } } @@ -124,7 +125,7 @@ class PersisterFolderService extends BasePersisterService { def jsonPath = getJsonPath(sf) def startTime = System.currentTimeMillis() - jsonPath.parent.toFile().mkdir() + jsonPath.parent.toFile().mkdirs() jsonPath.toFile().withPrintWriter { writer -> def json = toJson sf json = JsonOutput.toJson(json) From 855183397bd8bcd92451dbaf4d7e1a8f3ed6bed4 Mon Sep 17 00:00:00 2001 From: LoveIsGrief Date: Wed, 22 Jan 2020 21:35:54 +0100 Subject: [PATCH 10/16] Remove TODO There's already an issue open https://github.com/zlatinb/muwire/issues/35 --- .../com/muwire/core/files/PersisterFolderService.groovy | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy b/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy index 9e718532..5bf18eeb 100644 --- a/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy +++ b/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy @@ -95,10 +95,6 @@ class PersisterFolderService extends BasePersisterService { /** * Loads every JSON into memory - * - * TODO: Decide if this is a good idea - * The more shared files, the more we'll load in memory. - * It might not be necessary */ private void _load() { int loaded = 0 From 2935ee1a1d94ed2a800de57a82e30c712f4e1838 Mon Sep 17 00:00:00 2001 From: LoveIsGrief Date: Sat, 25 Jan 2020 14:49:59 +0100 Subject: [PATCH 11/16] Remove unnecessary executor It was doing nothing but starting and stopping --- .../main/groovy/com/muwire/core/files/PersisterService.groovy | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy b/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy index 31b3b610..272ff937 100644 --- a/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy +++ b/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy @@ -19,9 +19,6 @@ class PersisterService extends BasePersisterService { final int interval final Timer timer final FileManager fileManager - final ExecutorService persisterExecutor = Executors.newSingleThreadExecutor({ r -> - new Thread(r, "file persister") - } as ThreadFactory) PersisterService(File location, EventBus listener, int interval, FileManager fileManager) { this.location = location @@ -33,7 +30,6 @@ class PersisterService extends BasePersisterService { void stop() { timer.cancel() - persisterExecutor.shutdown() } void onUILoadedEvent(UILoadedEvent e) { From 56da9a16b09cdc959e0a8435ace00b6ec86978f7 Mon Sep 17 00:00:00 2001 From: LoveIsGrief Date: Sat, 25 Jan 2020 15:00:48 +0100 Subject: [PATCH 12/16] Set FileLoadedEvent::source in the subclass Setting it in the super class means we don't set the right value for every case --- .../groovy/com/muwire/core/files/BasePersisterService.groovy | 4 ++-- .../main/groovy/com/muwire/core/files/PersisterService.groovy | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/main/groovy/com/muwire/core/files/BasePersisterService.groovy b/core/src/main/groovy/com/muwire/core/files/BasePersisterService.groovy index b6d20163..fcb8313a 100644 --- a/core/src/main/groovy/com/muwire/core/files/BasePersisterService.groovy +++ b/core/src/main/groovy/com/muwire/core/files/BasePersisterService.groovy @@ -53,7 +53,7 @@ abstract class BasePersisterService extends Service{ Set sourceSet = sources.stream().map({ d -> new Destination(d.toString())}).collect Collectors.toSet() DownloadedFile df = new DownloadedFile(file, ih, pieceSize, sourceSet) df.setComment(json.comment) - return new FileLoadedEvent(loadedFile : df, source : "PersisterService") + return new FileLoadedEvent(loadedFile : df) } @@ -71,7 +71,7 @@ abstract class BasePersisterService extends Service{ sf.hit(searcher, timestamp, query) } } - return new FileLoadedEvent(loadedFile: sf, source : "PersisterService") + return new FileLoadedEvent(loadedFile: sf) } diff --git a/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy b/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy index 272ff937..a7a861cf 100644 --- a/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy +++ b/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy @@ -49,6 +49,7 @@ class PersisterService extends BasePersisterService { def event = fromJson parsed if (event != null) { log.fine("loaded file $event.loadedFile.file") + event.source = "PersisterService" listener.publish event loaded++ if (loaded % 10 == 0) From 4bc04ae6319305f71f7cdd38e76e246f5a53a404 Mon Sep 17 00:00:00 2001 From: LoveIsGrief Date: Sat, 25 Jan 2020 15:01:21 +0100 Subject: [PATCH 13/16] Revert "Reduce log levels in Connection" This reverts commit dcd233b7 --- .../main/groovy/com/muwire/core/connection/Connection.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/groovy/com/muwire/core/connection/Connection.groovy b/core/src/main/groovy/com/muwire/core/connection/Connection.groovy index 69e525f8..39b9ab82 100644 --- a/core/src/main/groovy/com/muwire/core/connection/Connection.groovy +++ b/core/src/main/groovy/com/muwire/core/connection/Connection.groovy @@ -88,11 +88,11 @@ abstract class Connection implements Closeable { log.log(Level.WARNING, "$name already closed", new Exception() ) return } - log.fine("closing $name") + log.info("closing $name") reader.interrupt() writer.interrupt() endpoint.close() - log.fine("closed $name") + log.info("closed $name") eventBus.publish(new DisconnectionEvent(destination: endpoint.destination)) } From a2b37ef567655595019d08ab11936088693edbd8 Mon Sep 17 00:00:00 2001 From: LoveIsGrief Date: Sat, 25 Jan 2020 15:06:12 +0100 Subject: [PATCH 14/16] Persist downloaded files --- core/src/main/groovy/com/muwire/core/Core.groovy | 1 + .../com/muwire/core/files/PersisterFolderService.groovy | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/core/src/main/groovy/com/muwire/core/Core.groovy b/core/src/main/groovy/com/muwire/core/Core.groovy index 8f770081..c0dda2ba 100644 --- a/core/src/main/groovy/com/muwire/core/Core.groovy +++ b/core/src/main/groovy/com/muwire/core/Core.groovy @@ -264,6 +264,7 @@ public class Core { log.info "initializing folder persistence service" persisterFolderService = new PersisterFolderService(new File(home, "files"), eventBus) eventBus.register(PersisterDoneEvent.class, persisterFolderService) + eventBus.register(FileDownloadedEvent.class, persisterFolderService) eventBus.register(FileLoadedEvent.class, persisterFolderService) eventBus.register(FileHashedEvent.class, persisterFolderService) eventBus.register(FileUnsharedEvent.class, persisterFolderService) diff --git a/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy b/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy index 5bf18eeb..7ed4daaf 100644 --- a/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy +++ b/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy @@ -56,6 +56,11 @@ class PersisterFolderService extends BasePersisterService { void onFileHashedEvent(FileHashedEvent hashedEvent) { persistFile(hashedEvent.sharedFile) } + + void onFileDownloadedEvent(FileDownloadedEvent downloadedEvent) { + persistFile(downloadedEvent.downloadedFile) + } + /** * Get rid of the json of unshared files * @param unsharedEvent From aa56cc23c0de360a44b71b1252f30d026eff7298 Mon Sep 17 00:00:00 2001 From: LoveIsGrief Date: Sat, 25 Jan 2020 15:20:38 +0100 Subject: [PATCH 15/16] Cache base 64 path hash Can't do it in constructor without an ugly try/catch therefore this is done on demand --- core/src/main/java/com/muwire/core/SharedFile.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/muwire/core/SharedFile.java b/core/src/main/java/com/muwire/core/SharedFile.java index c79ef9d5..5f238960 100644 --- a/core/src/main/java/com/muwire/core/SharedFile.java +++ b/core/src/main/java/com/muwire/core/SharedFile.java @@ -23,7 +23,8 @@ public class SharedFile { private final String cachedPath; private final long cachedLength; - + + private String b64PathHash; private final String b64EncodedFileName; private final String b64EncodedHashRoot; private final List b64EncodedHashList; @@ -40,7 +41,7 @@ public class SharedFile { this.cachedLength = file.length(); this.b64EncodedFileName = Base64.encode(DataUtil.encodei18nString(file.toString())); this.b64EncodedHashRoot = Base64.encode(infoHash.getRoot()); - + List b64List = new ArrayList(); byte[] tmp = new byte[32]; for (int i = 0; i < infoHash.getHashList().length / 32; i++) { @@ -61,7 +62,10 @@ public class SharedFile { } public String getB64PathHash() throws NoSuchAlgorithmException { - return Base64.encode(getPathHash()); + if(b64PathHash == null){ + b64PathHash = Base64.encode(getPathHash()); + } + return b64PathHash; } public InfoHash getInfoHash() { From a891c83518aa7b02c9b3c1d6befcbf84100cc66e Mon Sep 17 00:00:00 2001 From: LoveIsGrief Date: Sat, 25 Jan 2020 15:25:48 +0100 Subject: [PATCH 16/16] Only persist downloaded files if sharing thereof is enabled Otherwise we might inadvertently share downloads --- core/src/main/groovy/com/muwire/core/Core.groovy | 2 +- .../com/muwire/core/files/PersisterFolderService.groovy | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/core/src/main/groovy/com/muwire/core/Core.groovy b/core/src/main/groovy/com/muwire/core/Core.groovy index c0dda2ba..b9cb5985 100644 --- a/core/src/main/groovy/com/muwire/core/Core.groovy +++ b/core/src/main/groovy/com/muwire/core/Core.groovy @@ -262,7 +262,7 @@ public class Core { eventBus.register(UILoadedEvent.class, persisterService) log.info "initializing folder persistence service" - persisterFolderService = new PersisterFolderService(new File(home, "files"), eventBus) + persisterFolderService = new PersisterFolderService(this, new File(home, "files"), eventBus) eventBus.register(PersisterDoneEvent.class, persisterFolderService) eventBus.register(FileDownloadedEvent.class, persisterFolderService) eventBus.register(FileLoadedEvent.class, persisterFolderService) diff --git a/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy b/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy index 7ed4daaf..f58b5db0 100644 --- a/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy +++ b/core/src/main/groovy/com/muwire/core/files/PersisterFolderService.groovy @@ -28,6 +28,7 @@ class PersisterFolderService extends BasePersisterService { final static int CUT_LENGTH = 6 + private final Core core; final File location final EventBus listener final int interval @@ -36,7 +37,8 @@ class PersisterFolderService extends BasePersisterService { new Thread(r, "file persister") } as ThreadFactory) - PersisterFolderService(File location, EventBus listener) { + PersisterFolderService(Core core, File location, EventBus listener) { + this.core = core; this.location = location this.listener = listener this.interval = interval @@ -58,7 +60,9 @@ class PersisterFolderService extends BasePersisterService { } void onFileDownloadedEvent(FileDownloadedEvent downloadedEvent) { - persistFile(downloadedEvent.downloadedFile) + if (core.getMuOptions().getShareDownloadedFiles()) { + persistFile(downloadedEvent.downloadedFile) + } } /**