Compare commits

...

14 Commits

Author SHA1 Message Date
51425bbfd9 Release 0.3.8 2019-06-24 07:38:39 +01:00
6a4879bc0b always save pieces 2019-06-24 07:29:49 +01:00
e7fe56439b persist X-Have, fix flickering bug 2019-06-24 07:20:53 +01:00
2886feab4a do not modify the set of available pieces 2019-06-23 17:08:07 +01:00
fb91194026 even noisier log 2019-06-23 16:39:38 +01:00
4527478b0d even noisier 4_ 2019-06-23 12:42:44 +01:00
b0062f146e log roots of download exceptions 2019-06-23 12:10:19 +01:00
bf16561170 Release 0.3.7 2019-06-23 11:25:19 +01:00
3b23dc29c4 if all sources are expired forget mesh 2019-06-23 11:21:39 +01:00
c0645b670e no split on list 2019-06-23 10:50:19 +01:00
30613fe530 update todo 2019-06-23 09:56:51 +01:00
e7822f6edc expire sources, fix compilation 2019-06-23 09:43:56 +01:00
7e5c9ba115 actually save 2019-06-23 09:41:20 +01:00
647fa3a481 persist download mesh 2019-06-23 09:38:42 +01:00
10 changed files with 77 additions and 11 deletions

View File

@ -38,4 +38,3 @@ To enable parsing of metadata from known file types and the user editing it or a
* Download file sequentially
* Unsharing of files
* Multiple-selection download, Ctrl-A
* Pause/Resume downloads

View File

@ -35,7 +35,7 @@ class Cli {
Core core
try {
core = new Core(props, home, "0.3.6")
core = new Core(props, home, "0.3.8")
} catch (Exception bad) {
bad.printStackTrace(System.out)
println "Failed to initialize core, exiting"

View File

@ -53,7 +53,7 @@ class CliDownloader {
Core core
try {
core = new Core(props, home, "0.3.6")
core = new Core(props, home, "0.3.8")
} catch (Exception bad) {
bad.printStackTrace(System.out)
println "Failed to initialize core, exiting"

View File

@ -173,7 +173,7 @@ public class Core {
eventBus.register(SearchEvent.class, fileManager)
log.info("initializing mesh manager")
MeshManager meshManager = new MeshManager(fileManager)
MeshManager meshManager = new MeshManager(fileManager, home)
eventBus.register(SourceDiscoveredEvent.class, meshManager)
log.info "initializing persistence service"
@ -297,7 +297,7 @@ public class Core {
}
}
Core core = new Core(props, home, "0.3.6")
Core core = new Core(props, home, "0.3.8")
core.startServices()
// ... at the end, sleep or execute script

View File

@ -75,7 +75,7 @@ class DownloadSession {
if (available.isEmpty())
piece = pieces.claim()
else
piece = pieces.claim(available)
piece = pieces.claim(new HashSet<>(available))
if (piece == -1)
return false
boolean unclaim = true

View File

@ -18,6 +18,7 @@ import com.muwire.core.DownloadedFile
import com.muwire.core.EventBus
import com.muwire.core.connection.I2PConnector
import com.muwire.core.files.FileDownloadedEvent
import com.muwire.core.util.DataUtil
import groovy.util.logging.Log
import net.i2p.data.Destination
@ -269,7 +270,7 @@ public class Downloader {
writePieces()
}
} catch (Exception bad) {
log.log(Level.WARNING,"Exception while downloading",bad)
log.log(Level.WARNING,"Exception while downloading",DataUtil.findRoot(bad))
} finally {
currentState = WorkerState.FINISHED
if (pieces.isComplete() && eventFired.compareAndSet(false, true)) {

View File

@ -1,18 +1,31 @@
package com.muwire.core.mesh
import java.util.stream.Collectors
import com.muwire.core.Constants
import com.muwire.core.InfoHash
import com.muwire.core.Persona
import com.muwire.core.download.Pieces
import com.muwire.core.download.SourceDiscoveredEvent
import com.muwire.core.files.FileManager
import com.muwire.core.util.DataUtil
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import net.i2p.data.Base64
class MeshManager {
private static final int EXPIRATION = 60 * 60 * 1000
private final Map<InfoHash, Mesh> meshes = Collections.synchronizedMap(new HashMap<>())
private final FileManager fileManager
private final File home
MeshManager(FileManager fileManager) {
MeshManager(FileManager fileManager, File home) {
this.fileManager = fileManager
this.home = home
load()
}
Mesh get(InfoHash infoHash) {
@ -38,6 +51,51 @@ class MeshManager {
Mesh mesh = meshes.get(e.infoHash)
if (mesh == null)
return
mesh.sources.add(e.source)
mesh.sources.add(e.source)
save()
}
private void save() {
File meshFile = new File(home, "mesh.json")
synchronized(meshes) {
meshFile.withPrintWriter { writer ->
meshes.values().each { mesh ->
def json = [:]
json.timestamp = System.currentTimeMillis()
json.infoHash = Base64.encode(mesh.infoHash.getRoot())
json.sources = mesh.sources.stream().map({it.toBase64()}).collect(Collectors.toList())
json.nPieces = mesh.pieces.nPieces
json.xHave = DataUtil.encodeXHave(mesh.pieces.downloaded, mesh.pieces.nPieces)
writer.println(JsonOutput.toJson(json))
}
}
}
}
private void load() {
File meshFile = new File(home, "mesh.json")
if (!meshFile.exists())
return
long now = System.currentTimeMillis()
JsonSlurper slurper = new JsonSlurper()
meshFile.eachLine {
def json = slurper.parseText(it)
if (now - json.timestamp > EXPIRATION)
return
InfoHash infoHash = new InfoHash(Base64.decode(json.infoHash))
Pieces pieces = new Pieces(json.nPieces, Constants.DOWNLOAD_SEQUENTIAL_RATIO)
Mesh mesh = new Mesh(infoHash, pieces)
json.sources.each { source ->
Persona persona = new Persona(new ByteArrayInputStream(Base64.decode(source)))
mesh.sources.add(persona)
}
if (json.xHave != null)
DataUtil.decodeXHave(json.xHave).each { pieces.markDownloaded(it) }
if (!mesh.sources.isEmpty())
meshes.put(infoHash, mesh)
}
}
}

View File

@ -109,4 +109,10 @@ class DataUtil {
}
available
}
public static Exception findRoot(Exception e) {
while(e.getCause() != null)
e = e.getCause()
e
}
}

View File

@ -1,5 +1,5 @@
group = com.muwire
version = 0.3.6
version = 0.3.8
groovyVersion = 2.4.15
slf4jVersion = 1.7.25
spockVersion = 1.1-groovy-2.4

View File

@ -35,7 +35,7 @@ handlers= java.util.logging.FileHandler
# default file output is in user's home directory.
java.util.logging.FileHandler.pattern = MuWire.log
java.util.logging.FileHandler.limit = 50000000
java.util.logging.FileHandler.limit = 150000000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
@ -60,3 +60,5 @@ java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$
# messages:
com.xyz.foo.level = SEVERE
com.muwire.core.level = FINE
net.i2p.client.streaming.impl.level = FINE
net.i2p.client.impl.level = FINE