From ced9574e5e25d2b0f4cddfd5a58a67618998350f Mon Sep 17 00:00:00 2001 From: Kleissner Date: Tue, 14 Dec 2021 01:27:04 +0100 Subject: [PATCH] webapi: Live download implementation. --- ...{Download Temp.go => Download Transfer.go} | 76 ++++++++++++++----- webapi/Download.go | 4 + 2 files changed, 63 insertions(+), 17 deletions(-) rename webapi/{Download Temp.go => Download Transfer.go} (60%) diff --git a/webapi/Download Temp.go b/webapi/Download Transfer.go similarity index 60% rename from webapi/Download Temp.go rename to webapi/Download Transfer.go index 07d2b00..2312c87 100644 --- a/webapi/Download Temp.go +++ b/webapi/Download Transfer.go @@ -1,5 +1,5 @@ /* -File Name: Download Temp.go +File Name: Download Transfer.go Copyright: 2021 Peernet Foundation s.r.o. Author: Peter Kleissner @@ -9,32 +9,78 @@ Temporary download code to provide dummy results for testing. To be replaced! package webapi import ( - "math/rand" "os" "time" + + "github.com/PeernetOfficial/core" ) -// Start is a dummy downloader +// Starts the download. func (info *downloadInfo) Start() { - time.Sleep(time.Second * time.Duration(rand.Intn(5))) + for n := 0; n < 3 && info.peer == nil; n++ { + _, info.peer, _ = core.FindNode(info.nodeID, time.Second*5) - // request metadata - //info.file = blockRecordFileToAPI(createTestResult(-1)) + if info.status == DownloadCanceled { + return + } + } - // join swarm + if info.peer != nil { + info.Download() + } else { + info.status = DownloadCanceled + } +} +func (info *downloadInfo) Download() { + //fmt.Printf("Download start of %s\n", hex.EncodeToString(info.hash)) + + // try to download the entire file + reader, fileSize, transferSize, err := FileStartReader(info.peer, info.hash, 0, 0, nil) + if reader != nil { + defer reader.Close() + } + if err != nil { + info.status = DownloadCanceled + return + } else if fileSize != transferSize { + info.status = DownloadCanceled + return + } + + info.file.Size = fileSize info.status = DownloadActive - // start download - for n := uint64(0); n < 10; n++ { - time.Sleep(time.Second * time.Duration(rand.Intn(5))) + // download in a loop + var fileOffset, totalRead uint64 + dataRemaining := fileSize + readSize := uint64(4096) - randomData := make([]byte, info.file.Size/10) - rand.Read(randomData) + for dataRemaining > 0 { + //fmt.Printf("data remaining: downloaded %d from total %d = %d %%\n", totalRead, fileSize, totalRead*100/fileSize) + if dataRemaining < readSize { + readSize = dataRemaining + } - info.storeDownloadData(randomData, n*info.file.Size/10) + data := make([]byte, readSize) + n, err := reader.Read(data) + + totalRead += uint64(n) + dataRemaining -= uint64(n) + data = data[:n] + + if err != nil { + info.status = DownloadCanceled + return + } + + info.storeDownloadData(data[:n], fileOffset) + + fileOffset += uint64(n) } + //fmt.Printf("data finished: downloaded %d from total %d = %d %%\n", totalRead, fileSize, totalRead*100/fileSize) + info.Finish() info.DeleteDefer(time.Hour * 1) // cache the details for 1 hour before removing } @@ -114,10 +160,6 @@ func (info *downloadInfo) storeDownloadData(data []byte, offset uint64) (status return DownloadResponseActionInvalid } - //if _, err := info.DiskFile.Handle.Seek(int64(offset), 0); err != nil { - // return err - //} - if _, err := info.DiskFile.Handle.WriteAt(data, int64(offset)); err != nil { return DownloadResponseFileWrite } diff --git a/webapi/Download.go b/webapi/Download.go index d5c958a..ee0b532 100644 --- a/webapi/Download.go +++ b/webapi/Download.go @@ -15,6 +15,7 @@ import ( "sync" "time" + "github.com/PeernetOfficial/core" "github.com/google/uuid" ) @@ -199,6 +200,9 @@ type downloadInfo struct { Swarm struct { // Information about the swarm. Only valid for status >= DownloadActive. CountPeers uint64 // Count of peers participating in the swarm. } + + // live connections, to be changed + peer *core.PeerInfo } var (