Compare commits

...

13 Commits

Author SHA1 Message Date
Zlatin Balevsky
e829e09b13 fix piece count calculation 2019-06-24 18:22:46 +01:00
Zlatin Balevsky
120980100b log mesh creation 2019-06-24 18:11:55 +01:00
Zlatin Balevsky
e64ed2c89d fix method name 2019-06-24 18:03:22 +01:00
Zlatin Balevsky
81436aaa66 fix name 2019-06-24 17:59:39 +01:00
Zlatin Balevsky
3bb530e34f more logging 2019-06-24 17:50:07 +01:00
Zlatin Balevsky
51425bbfd9 Release 0.3.8 2019-06-24 07:38:39 +01:00
Zlatin Balevsky
6a4879bc0b always save pieces 2019-06-24 07:29:49 +01:00
Zlatin Balevsky
e7fe56439b persist X-Have, fix flickering bug 2019-06-24 07:20:53 +01:00
Zlatin Balevsky
2886feab4a do not modify the set of available pieces 2019-06-23 17:08:07 +01:00
Zlatin Balevsky
fb91194026 even noisier log 2019-06-23 16:39:38 +01:00
Zlatin Balevsky
4527478b0d even noisier 4_ 2019-06-23 12:42:44 +01:00
Zlatin Balevsky
b0062f146e log roots of download exceptions 2019-06-23 12:10:19 +01:00
Zlatin Balevsky
bf16561170 Release 0.3.7 2019-06-23 11:25:19 +01:00
11 changed files with 34 additions and 10 deletions

View File

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

View File

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

View File

@@ -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() core.startServices()
// ... at the end, sleep or execute script // ... at the end, sleep or execute script

View File

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

View File

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

View File

@@ -1,5 +1,6 @@
package com.muwire.core.mesh package com.muwire.core.mesh
import java.util.logging.Level
import java.util.stream.Collectors import java.util.stream.Collectors
import com.muwire.core.Constants import com.muwire.core.Constants
@@ -8,11 +9,14 @@ import com.muwire.core.Persona
import com.muwire.core.download.Pieces import com.muwire.core.download.Pieces
import com.muwire.core.download.SourceDiscoveredEvent import com.muwire.core.download.SourceDiscoveredEvent
import com.muwire.core.files.FileManager import com.muwire.core.files.FileManager
import com.muwire.core.util.DataUtil
import groovy.json.JsonOutput import groovy.json.JsonOutput
import groovy.json.JsonSlurper import groovy.json.JsonSlurper
import groovy.util.logging.Log
import net.i2p.data.Base64 import net.i2p.data.Base64
@Log
class MeshManager { class MeshManager {
private static final int EXPIRATION = 60 * 60 * 1000 private static final int EXPIRATION = 60 * 60 * 1000
@@ -35,6 +39,7 @@ class MeshManager {
synchronized(meshes) { synchronized(meshes) {
if (meshes.containsKey(infoHash)) if (meshes.containsKey(infoHash))
return meshes.get(infoHash) return meshes.get(infoHash)
log.log(Level.INFO,"creating mesh with pieces:$nPieces", new Exception())
Pieces pieces = new Pieces(nPieces, Constants.DOWNLOAD_SEQUENTIAL_RATIO) Pieces pieces = new Pieces(nPieces, Constants.DOWNLOAD_SEQUENTIAL_RATIO)
if (fileManager.rootToFiles.containsKey(infoHash)) { if (fileManager.rootToFiles.containsKey(infoHash)) {
for (int i = 0; i < nPieces; i++) for (int i = 0; i < nPieces; i++)
@@ -50,8 +55,8 @@ class MeshManager {
Mesh mesh = meshes.get(e.infoHash) Mesh mesh = meshes.get(e.infoHash)
if (mesh == null) if (mesh == null)
return return
if (mesh.sources.add(e.source)) mesh.sources.add(e.source)
save() save()
} }
private void save() { private void save() {
@@ -64,6 +69,7 @@ class MeshManager {
json.infoHash = Base64.encode(mesh.infoHash.getRoot()) json.infoHash = Base64.encode(mesh.infoHash.getRoot())
json.sources = mesh.sources.stream().map({it.toBase64()}).collect(Collectors.toList()) json.sources = mesh.sources.stream().map({it.toBase64()}).collect(Collectors.toList())
json.nPieces = mesh.pieces.nPieces json.nPieces = mesh.pieces.nPieces
json.xHave = DataUtil.encodeXHave(mesh.pieces.downloaded, mesh.pieces.nPieces)
writer.println(JsonOutput.toJson(json)) writer.println(JsonOutput.toJson(json))
} }
} }
@@ -89,6 +95,9 @@ class MeshManager {
mesh.sources.add(persona) mesh.sources.add(persona)
} }
if (json.xHave != null)
DataUtil.decodeXHave(json.xHave).each { pieces.markDownloaded(it) }
if (!mesh.sources.isEmpty()) if (!mesh.sources.isEmpty())
meshes.put(infoHash, mesh) meshes.put(infoHash, mesh)
} }

View File

@@ -12,8 +12,10 @@ import com.muwire.core.connection.Endpoint
import com.muwire.core.mesh.Mesh import com.muwire.core.mesh.Mesh
import com.muwire.core.util.DataUtil import com.muwire.core.util.DataUtil
import groovy.util.logging.Log
import net.i2p.data.Destination import net.i2p.data.Destination
@Log
class ContentUploader extends Uploader { class ContentUploader extends Uploader {
private final File file private final File file
@@ -42,8 +44,10 @@ class ContentUploader extends Uploader {
int endPiece = range.end / (0x1 << pieceSize) int endPiece = range.end / (0x1 << pieceSize)
for (int i = startPiece; i <= endPiece; i++) for (int i = startPiece; i <= endPiece; i++)
satisfiable &= mesh.pieces.isDownloaded(i) satisfiable &= mesh.pieces.isDownloaded(i)
log.info("requested range $range.start-$range.end startPiece:$startPiece endPiece:$endPiece satisfiable:$satisfiable my pieces: ${mesh.pieces.getDownloaded()}")
} }
if (!satisfiable) { if (!satisfiable) {
log.info("416 range not satisfiable")
os.write("416 Range Not Satisfiable\r\n".getBytes(StandardCharsets.US_ASCII)) os.write("416 Range Not Satisfiable\r\n".getBytes(StandardCharsets.US_ASCII))
writeMesh(request.downloader) writeMesh(request.downloader)
os.write("\r\n".getBytes(StandardCharsets.US_ASCII)) os.write("\r\n".getBytes(StandardCharsets.US_ASCII))
@@ -51,6 +55,8 @@ class ContentUploader extends Uploader {
return return
} }
log.info("200 ok")
os.write("200 OK\r\n".getBytes(StandardCharsets.US_ASCII)) os.write("200 OK\r\n".getBytes(StandardCharsets.US_ASCII))
os.write("Content-Range: $range.start-$range.end\r\n".getBytes(StandardCharsets.US_ASCII)) os.write("Content-Range: $range.start-$range.end\r\n".getBytes(StandardCharsets.US_ASCII))
writeMesh(request.downloader) writeMesh(request.downloader)

View File

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

View File

@@ -30,7 +30,7 @@ public class SharedFile {
long length = file.length(); long length = file.length();
int rawPieceSize = 0x1 << pieceSize; int rawPieceSize = 0x1 << pieceSize;
int rv = (int) (length / rawPieceSize); int rv = (int) (length / rawPieceSize);
if (length % pieceSize != 0) if (length % rawPieceSize != 0)
rv++; rv++;
return rv; return rv;
} }

View File

@@ -1,5 +1,5 @@
group = com.muwire group = com.muwire
version = 0.3.6 version = 0.3.8
groovyVersion = 2.4.15 groovyVersion = 2.4.15
slf4jVersion = 1.7.25 slf4jVersion = 1.7.25
spockVersion = 1.1-groovy-2.4 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. # default file output is in user's home directory.
java.util.logging.FileHandler.pattern = MuWire.log 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.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter 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: # messages:
com.xyz.foo.level = SEVERE com.xyz.foo.level = SEVERE
com.muwire.core.level = FINE com.muwire.core.level = FINE
net.i2p.client.streaming.impl.level = FINE
net.i2p.client.impl.level = FINE