use of callback instead of channel'

This commit is contained in:
ap-pauloafonso 2021-03-18 18:42:30 -03:00
parent 8a630643bb
commit 1e72341df7
5 changed files with 34 additions and 50 deletions

View file

@ -1,8 +1,8 @@
package bencode package bencode
import ( import (
"io/ioutil"
"log" "log"
"os"
"reflect" "reflect"
"testing" "testing"
) )
@ -99,13 +99,13 @@ func TestMapParse(T *testing.T) {
func TestDecode(T *testing.T) { func TestDecode(T *testing.T) {
files, err := ioutil.ReadDir("./torrent_files_test") files, err := os.ReadDir("./torrent_files_test")
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
for _, f := range files { for _, f := range files {
T.Run(f.Name(), func(t *testing.T) { T.Run(f.Name(), func(t *testing.T) {
data, _ := ioutil.ReadFile("./torrent_files_test/" + f.Name()) data, _ := os.ReadFile("./torrent_files_test/" + f.Name())
result, _ := Decode(data) result, _ := Decode(data)
t.Log(result["info"].(map[string]interface{})["name"]) t.Log(result["info"].(map[string]interface{})["name"])
}) })

View file

@ -3,7 +3,7 @@ package emulation
import ( import (
"embed" "embed"
"encoding/json" "encoding/json"
"io/ioutil" "io"
"github.com/ap-pauloafonso/ratio-spoof/internal/generator" "github.com/ap-pauloafonso/ratio-spoof/internal/generator"
) )
@ -83,7 +83,7 @@ func extractClient(code string) (*ClientInfo, error) {
} }
defer f.Close() defer f.Close()
bytes, err := ioutil.ReadAll(f) bytes, err := io.ReadAll(f)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -2,7 +2,7 @@ package generator
import "testing" import "testing"
func TestNextAmountReport(t *testing.T) { func TestDefaultRounding(t *testing.T) {
r, _ := NewDefaultRoudingGenerator() r, _ := NewDefaultRoudingGenerator()
d, u, l := r.Round(656497856, 46479878, 7879879, 1024) d, u, l := r.Round(656497856, 46479878, 7879879, 1024)

View file

@ -3,13 +3,11 @@ package ratiospoof
import ( import (
"errors" "errors"
"fmt" "fmt"
"io/ioutil"
"log" "log"
"math/rand" "math/rand"
"os" "os"
"os/signal" "os/signal"
"strings" "strings"
"sync"
"syscall" "syscall"
"time" "time"
@ -25,21 +23,19 @@ const (
) )
type RatioSpoof struct { type RatioSpoof struct {
mutex *sync.Mutex TorrentInfo *bencode.TorrentInfo
TorrentInfo *bencode.TorrentInfo Input *input.InputParsed
Input *input.InputParsed Tracker *tracker.HttpTracker
Tracker *tracker.HttpTracker BitTorrentClient *emulation.Emulation
BitTorrentClient *emulation.Emulation AnnounceInterval int
AnnounceInterval int EstimatedTimeToAnnounce time.Time
EstimatedTimeToAnnounce time.Time NumWant int
EstimatedTimeToAnnounceUpdateCh chan int Seeders int
NumWant int Leechers int
Seeders int AnnounceCount int
Leechers int Status string
AnnounceCount int AnnounceHistory announceHistory
Status string StopPrintCH chan interface{}
AnnounceHistory announceHistory
StopPrintCH chan interface{}
} }
type AnnounceEntry struct { type AnnounceEntry struct {
@ -55,9 +51,8 @@ type announceHistory struct {
} }
func NewRatioSpoofState(input input.InputArgs) (*RatioSpoof, error) { func NewRatioSpoofState(input input.InputArgs) (*RatioSpoof, error) {
EstimatedTimeToAnnounceUpdateCh := make(chan int)
stopPrintCh := make(chan interface{}) stopPrintCh := make(chan interface{})
dat, err := ioutil.ReadFile(input.TorrentPath) dat, err := os.ReadFile(input.TorrentPath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -83,15 +78,13 @@ func NewRatioSpoofState(input input.InputArgs) (*RatioSpoof, error) {
} }
return &RatioSpoof{ return &RatioSpoof{
BitTorrentClient: client, BitTorrentClient: client,
TorrentInfo: torrentInfo, TorrentInfo: torrentInfo,
Tracker: httpTracker, Tracker: httpTracker,
Input: inputParsed, Input: inputParsed,
NumWant: 200, NumWant: 200,
Status: "started", Status: "started",
mutex: &sync.Mutex{}, StopPrintCH: stopPrintCh,
StopPrintCH: stopPrintCh,
EstimatedTimeToAnnounceUpdateCh: EstimatedTimeToAnnounceUpdateCh,
}, nil }, nil
} }
@ -117,7 +110,6 @@ func (R *RatioSpoof) Run() {
signal.Notify(sigCh, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) signal.Notify(sigCh, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
R.firstAnnounce() R.firstAnnounce()
go R.updateEstimatedTimeToAnnounceListener()
go func() { go func() {
for { for {
R.generateNextAnnounce() R.generateNextAnnounce()
@ -140,22 +132,14 @@ func (R *RatioSpoof) updateInterval(interval int) {
} else { } else {
R.AnnounceInterval = 1800 R.AnnounceInterval = 1800
} }
R.AnnounceInterval = 30
R.updateEstimatedTimeToAnnounce(R.AnnounceInterval) R.updateEstimatedTimeToAnnounce(R.AnnounceInterval)
} }
func (R *RatioSpoof) updateEstimatedTimeToAnnounce(interval int) { func (R *RatioSpoof) updateEstimatedTimeToAnnounce(interval int) {
R.mutex.Lock()
defer R.mutex.Unlock()
R.EstimatedTimeToAnnounce = time.Now().Add(time.Duration(interval) * time.Second) R.EstimatedTimeToAnnounce = time.Now().Add(time.Duration(interval) * time.Second)
} }
func (R *RatioSpoof) updateEstimatedTimeToAnnounceListener() {
for {
interval := <-R.EstimatedTimeToAnnounceUpdateCh
R.updateEstimatedTimeToAnnounce(interval)
}
}
func (R *RatioSpoof) updateSeedersAndLeechers(resp tracker.TrackerResponse) { func (R *RatioSpoof) updateSeedersAndLeechers(resp tracker.TrackerResponse) {
R.Seeders = resp.Seeders R.Seeders = resp.Seeders
R.Leechers = resp.Leechers R.Leechers = resp.Leechers
@ -176,7 +160,7 @@ func (R *RatioSpoof) fireAnnounce(retry bool) error {
"{event}", R.Status, "{event}", R.Status,
"{numwant}", fmt.Sprint(R.NumWant)) "{numwant}", fmt.Sprint(R.NumWant))
query := replacer.Replace(R.BitTorrentClient.Query) query := replacer.Replace(R.BitTorrentClient.Query)
trackerResp, err := R.Tracker.Announce(query, R.BitTorrentClient.Headers, retry, R.EstimatedTimeToAnnounceUpdateCh) trackerResp, err := R.Tracker.Announce(query, R.BitTorrentClient.Headers, retry, R.updateEstimatedTimeToAnnounce)
if err != nil { if err != nil {
log.Fatalf("failed to reach the tracker:\n%s ", err.Error()) log.Fatalf("failed to reach the tracker:\n%s ", err.Error())
} }

View file

@ -4,7 +4,7 @@ import (
"bytes" "bytes"
"compress/gzip" "compress/gzip"
"errors" "errors"
"io/ioutil" "io"
"net/http" "net/http"
"strings" "strings"
"time" "time"
@ -46,7 +46,7 @@ func (T *HttpTracker) SwapFirst(currentIdx int) {
T.Urls[currentIdx] = aux T.Urls[currentIdx] = aux
} }
func (T *HttpTracker) Announce(query string, headers map[string]string, retry bool, estimatedTimeToAnnounceUpdateCh chan<- int) (*TrackerResponse, error) { func (T *HttpTracker) Announce(query string, headers map[string]string, retry bool, callBack func(int)) (*TrackerResponse, error) {
defer func() { defer func() {
T.RetryAttempt = 0 T.RetryAttempt = 0
}() }()
@ -55,7 +55,7 @@ func (T *HttpTracker) Announce(query string, headers map[string]string, retry bo
for { for {
trackerResp, err := T.tryMakeRequest(query, headers) trackerResp, err := T.tryMakeRequest(query, headers)
if err != nil { if err != nil {
estimatedTimeToAnnounceUpdateCh <- retryDelay callBack(retryDelay)
T.RetryAttempt++ T.RetryAttempt++
time.Sleep(time.Duration(retryDelay) * time.Second) time.Sleep(time.Duration(retryDelay) * time.Second)
retryDelay *= 2 retryDelay *= 2
@ -87,14 +87,14 @@ func (t *HttpTracker) tryMakeRequest(query string, headers map[string]string) (*
resp, err := http.DefaultClient.Do(req) resp, err := http.DefaultClient.Do(req)
if err == nil { if err == nil {
if resp.StatusCode == http.StatusOK { if resp.StatusCode == http.StatusOK {
bytesR, _ := ioutil.ReadAll(resp.Body) bytesR, _ := io.ReadAll(resp.Body)
if len(bytesR) == 0 { if len(bytesR) == 0 {
continue continue
} }
mimeType := http.DetectContentType(bytesR) mimeType := http.DetectContentType(bytesR)
if mimeType == "application/x-gzip" { if mimeType == "application/x-gzip" {
gzipReader, _ := gzip.NewReader(bytes.NewReader(bytesR)) gzipReader, _ := gzip.NewReader(bytes.NewReader(bytesR))
bytesR, _ = ioutil.ReadAll(gzipReader) bytesR, _ = io.ReadAll(gzipReader)
gzipReader.Close() gzipReader.Close()
} }
t.LastTackerResponse = string(bytesR) t.LastTackerResponse = string(bytesR)