mirror of
https://github.com/ap-pauloafonso/ratio-spoof.git
synced 2026-05-07 18:49:33 +00:00
first pass at using ticker over handrolled timing
This commit is contained in:
parent
2b98b4ae5c
commit
aaeb5ae3c9
5 changed files with 80 additions and 61 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -128,7 +128,8 @@ dmypy.json
|
|||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
#vscode folder
|
||||
#ide folders
|
||||
/.vscode
|
||||
.idea
|
||||
|
||||
out/
|
||||
out/
|
||||
|
|
|
|||
4
go.mod
4
go.mod
|
|
@ -4,6 +4,8 @@ go 1.15
|
|||
|
||||
require (
|
||||
github.com/gammazero/deque v0.0.0-20201010052221-3932da5530cc
|
||||
github.com/magefile/mage v1.11.0 // indirect
|
||||
github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 // indirect
|
||||
github.com/sirupsen/logrus v1.8.0
|
||||
golang.org/x/sys v0.0.0-20210227040730-b0d1d43c014d // indirect
|
||||
)
|
||||
|
|
|
|||
11
go.sum
11
go.sum
|
|
@ -1,6 +1,17 @@
|
|||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gammazero/deque v0.0.0-20201010052221-3932da5530cc h1:F7BbnLACph7UYiz9ZHi6npcROwKaZUyviDjsNERsoMM=
|
||||
github.com/gammazero/deque v0.0.0-20201010052221-3932da5530cc/go.mod h1:IlBLfYXnuw9sspy1XS6ctu5exGb6WHGKQsyo4s7bOEA=
|
||||
github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g=
|
||||
github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
|
||||
github.com/magefile/mage v1.11.0 h1:C/55Ywp9BpgVVclD3lRnSYCwXTYxmSppIgLeDYlNuls=
|
||||
github.com/magefile/mage v1.11.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
|
||||
github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0 h1:LiZB1h0GIcudcDci2bxbqI6DXV8bF8POAnArqvRrIyw=
|
||||
github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0/go.mod h1:F/7q8/HZz+TXjlsoZQQKVYvXTZaFH4QRa3y+j1p7MS0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU=
|
||||
github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210227040730-b0d1d43c014d h1:9fH9JvLNoSpsDWcXJ4dSE3lZW99Z3OCUZLr07g60U6o=
|
||||
golang.org/x/sys v0.0.0-20210227040730-b0d1d43c014d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
|
|||
|
|
@ -10,12 +10,13 @@ import (
|
|||
|
||||
"github.com/ap-pauloafonso/ratio-spoof/internal/ratiospoof"
|
||||
"github.com/olekukonko/ts"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func PrintState(state *ratiospoof.RatioSpoof) {
|
||||
exit := false
|
||||
go func() {
|
||||
_ = <-state.StopPrintCH
|
||||
<-state.StopPrintCH
|
||||
exit = true
|
||||
}()
|
||||
|
||||
|
|
@ -62,12 +63,14 @@ func PrintState(state *ratiospoof.RatioSpoof) {
|
|||
fmt.Printf("#%v downloaded: %v(%.2f%%) | left: %v | uploaded: %v | announced\n", dequeItem.Count, humanReadableSize(float64(dequeItem.Downloaded)), dequeItem.PercentDownloaded, humanReadableSize(float64(dequeItem.Left)), humanReadableSize(float64(dequeItem.Uploaded)))
|
||||
}
|
||||
lastDequeItem := state.AnnounceHistory.At(state.AnnounceHistory.Len() - 1).(ratiospoof.AnnounceEntry)
|
||||
nextAnnounceSeconds := time.Until(state.NextAnnounce) * time.Second
|
||||
|
||||
fmt.Printf("#%v downloaded: %v(%.2f%%) | left: %v | uploaded: %v | next announce in: %v %v\n", lastDequeItem.Count,
|
||||
humanReadableSize(float64(lastDequeItem.Downloaded)),
|
||||
lastDequeItem.PercentDownloaded,
|
||||
humanReadableSize(float64(lastDequeItem.Left)),
|
||||
humanReadableSize(float64(lastDequeItem.Uploaded)),
|
||||
fmtDuration(state.CurrentAnnounceTimer),
|
||||
nextAnnounceSeconds,
|
||||
retryStr)
|
||||
|
||||
if state.Input.Debug {
|
||||
|
|
@ -91,7 +94,9 @@ func clear() {
|
|||
if runtime.GOOS == "windows" {
|
||||
cmd := exec.Command("cmd", "/c", "cls")
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Run()
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Warn("Failed to run printer.clear()", err)
|
||||
}
|
||||
} else {
|
||||
fmt.Print("\033c")
|
||||
}
|
||||
|
|
@ -113,8 +118,3 @@ func humanReadableSize(byteSize float64) string {
|
|||
}
|
||||
return fmt.Sprintf("%.2f%v", byteSize, unitFound)
|
||||
}
|
||||
|
||||
func fmtDuration(seconds int) string {
|
||||
d := time.Duration(seconds) * time.Second
|
||||
return fmt.Sprintf("%s", d)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,19 +4,19 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math/rand"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/gammazero/deque"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/ap-pauloafonso/ratio-spoof/internal/bencode"
|
||||
"github.com/ap-pauloafonso/ratio-spoof/internal/input"
|
||||
"github.com/ap-pauloafonso/ratio-spoof/internal/tracker"
|
||||
"github.com/gammazero/deque"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -24,21 +24,20 @@ const (
|
|||
)
|
||||
|
||||
type RatioSpoof struct {
|
||||
mutex *sync.Mutex
|
||||
TorrentInfo *bencode.TorrentInfo
|
||||
Input *input.InputParsed
|
||||
Tracker *tracker.HttpTracker
|
||||
BitTorrentClient TorrentClientEmulation
|
||||
CurrentAnnounceTimer int
|
||||
AnnounceInterval int
|
||||
NumWant int
|
||||
Seeders int
|
||||
Leechers int
|
||||
AnnounceCount int
|
||||
Status string
|
||||
AnnounceHistory announceHistory
|
||||
timerUpdateCh chan int
|
||||
StopPrintCH chan interface{}
|
||||
TorrentInfo *bencode.TorrentInfo
|
||||
Input *input.InputParsed
|
||||
Tracker *tracker.HttpTracker
|
||||
BitTorrentClient TorrentClientEmulation
|
||||
NextAnnounce time.Time
|
||||
AnnounceInterval int
|
||||
NumWant int
|
||||
Seeders int
|
||||
Leechers int
|
||||
AnnounceCount int
|
||||
Status string
|
||||
AnnounceHistory announceHistory
|
||||
timerUpdateCh chan int
|
||||
StopPrintCH chan interface{}
|
||||
}
|
||||
|
||||
type TorrentClientEmulation interface {
|
||||
|
|
@ -92,7 +91,6 @@ func NewRatioSpoofState(input input.InputArgs, torrentClient TorrentClientEmulat
|
|||
Input: inputParsed,
|
||||
NumWant: 200,
|
||||
Status: "started",
|
||||
mutex: &sync.Mutex{},
|
||||
timerUpdateCh: changeTimerCh,
|
||||
StopPrintCH: stopPrintCh,
|
||||
}, nil
|
||||
|
|
@ -109,33 +107,53 @@ func (R *RatioSpoof) gracefullyExit() {
|
|||
fmt.Printf("\nGracefully exiting...\n")
|
||||
R.Status = "stopped"
|
||||
R.NumWant = 0
|
||||
R.fireAnnounce(false)
|
||||
|
||||
if err := R.fireAnnounce(false); err != nil {
|
||||
log.Info("final fireAnnounce failed")
|
||||
}
|
||||
|
||||
fmt.Printf("Gracefully exited successfully.\n")
|
||||
|
||||
}
|
||||
|
||||
func (R *RatioSpoof) Run() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
sigCh := make(chan os.Signal)
|
||||
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
signal.Notify(sigCh, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
|
||||
R.firstAnnounce()
|
||||
go R.decreaseTimer()
|
||||
go R.updateTimer()
|
||||
go func() {
|
||||
for {
|
||||
|
||||
duration := time.Duration(R.AnnounceInterval) * time.Second
|
||||
ticker := time.NewTicker(duration)
|
||||
defer ticker.Stop()
|
||||
|
||||
runLoop := true
|
||||
|
||||
for runLoop {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
//TODO: Eliminate shared state
|
||||
R.NextAnnounce = time.Now().Add(duration)
|
||||
|
||||
if err := R.fireAnnounce(true); err != nil {
|
||||
//Log and continue (maintains former functionality)
|
||||
log.Warn("failed to fire announce", err)
|
||||
}
|
||||
|
||||
R.generateNextAnnounce()
|
||||
time.Sleep(time.Duration(R.AnnounceInterval) * time.Second)
|
||||
R.fireAnnounce(true)
|
||||
case <-sigCh:
|
||||
fmt.Println("done")
|
||||
runLoop = false
|
||||
}
|
||||
}()
|
||||
<-sigCh
|
||||
}
|
||||
|
||||
R.StopPrintCH <- "exit print"
|
||||
R.gracefullyExit()
|
||||
}
|
||||
func (R *RatioSpoof) firstAnnounce() {
|
||||
R.addAnnounce(R.Input.InitialDownloaded, R.Input.InitialUploaded, calculateBytesLeft(R.Input.InitialDownloaded, R.TorrentInfo.TotalSize), (float32(R.Input.InitialDownloaded)/float32(R.TorrentInfo.TotalSize))*100)
|
||||
R.fireAnnounce(false)
|
||||
if err := R.fireAnnounce(false); err != nil {
|
||||
log.Warn("failed to fire first announce", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (R *RatioSpoof) updateInterval(resp tracker.TrackerResponse) {
|
||||
|
|
@ -155,6 +173,12 @@ func (R *RatioSpoof) addAnnounce(currentDownloaded, currentUploaded, currentLeft
|
|||
R.AnnounceHistory.pushValueHistory(AnnounceEntry{Count: R.AnnounceCount, Downloaded: currentDownloaded, Uploaded: currentUploaded, Left: currentLeft, PercentDownloaded: percentDownloaded})
|
||||
}
|
||||
func (R *RatioSpoof) fireAnnounce(retry bool) error {
|
||||
//Guard against empty queue, Back() panics when empty
|
||||
if R.AnnounceHistory.Len() == 0 {
|
||||
log.Info("skipping fireAnnounce, queue empty")
|
||||
return nil
|
||||
}
|
||||
|
||||
lastAnnounce := R.AnnounceHistory.Back().(AnnounceEntry)
|
||||
replacer := strings.NewReplacer("{infohash}", R.TorrentInfo.InfoHashURLEncoded,
|
||||
"{port}", fmt.Sprint(R.Input.Port),
|
||||
|
|
@ -198,25 +222,6 @@ func (R *RatioSpoof) generateNextAnnounce() {
|
|||
|
||||
R.addAnnounce(d, u, l, (float32(d)/float32(R.TorrentInfo.TotalSize))*100)
|
||||
}
|
||||
func (R *RatioSpoof) decreaseTimer() {
|
||||
for {
|
||||
time.Sleep(1 * time.Second)
|
||||
R.mutex.Lock()
|
||||
if R.CurrentAnnounceTimer > 0 {
|
||||
R.CurrentAnnounceTimer--
|
||||
}
|
||||
R.mutex.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (R *RatioSpoof) updateTimer() {
|
||||
for {
|
||||
newValue := <-R.timerUpdateCh
|
||||
R.mutex.Lock()
|
||||
R.CurrentAnnounceTimer = newValue
|
||||
R.mutex.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func calculateNextTotalSizeByte(speedBytePerSecond, currentByte, pieceSizeByte, seconds, limitTotalBytes int) int {
|
||||
if speedBytePerSecond == 0 {
|
||||
|
|
|
|||
Loading…
Reference in a new issue