This commit is contained in:
YouROK
2020-11-10 14:06:13 +03:00
parent c95eaccc57
commit 6a11651cf5
15 changed files with 566 additions and 209 deletions

View File

@@ -83,6 +83,9 @@ func (bt *BTServer) configure() {
bt.config.HTTPUserAgent = userAgent
bt.config.ExtendedHandshakeClientVersion = cliVers
bt.config.EstablishedConnsPerTorrent = settings.BTsets.ConnectionsLimit
bt.config.DefaultRequestStrategy = torrent.RequestStrategyFastest()
if settings.BTsets.DhtConnectionLimit > 0 {
bt.config.ConnTracker.SetMaxEntries(settings.BTsets.DhtConnectionLimit)
}

View File

@@ -1,130 +0,0 @@
package torr
import (
"fmt"
"sort"
"github.com/anacrolix/torrent"
)
type BTState struct {
LocalPort int
PeerID string
BannedIPs int
DHTs []torrent.DhtServer
Torrents []*Torrent
}
func (bt *BTServer) BTState() *BTState {
bt.mu.Lock()
defer bt.mu.Unlock()
btState := new(BTState)
btState.LocalPort = bt.client.LocalPort()
btState.PeerID = fmt.Sprintf("%x", bt.client.PeerID())
btState.BannedIPs = len(bt.client.BadPeerIPs())
btState.DHTs = bt.client.DhtServers()
for _, t := range bt.torrents {
btState.Torrents = append(btState.Torrents, t)
}
return btState
}
type TorrentStats struct {
Name string `json:"name,omitempty"`
Hash string `json:"hash,omitempty"`
TorrentStatus TorrentStatus `json:"torrent_status,omitempty"`
TorrentStatusString string `json:"torrent_status_string,omitempty"`
LoadedSize int64 `json:"loaded_size,omitempty"`
TorrentSize int64 `json:"torrent_size,omitempty"`
PreloadedBytes int64 `json:"preloaded_bytes,omitempty"`
PreloadSize int64 `json:"preload_size,omitempty"`
DownloadSpeed float64 `json:"download_speed,omitempty"`
UploadSpeed float64 `json:"upload_speed,omitempty"`
TotalPeers int `json:"total_peers,omitempty"`
PendingPeers int `json:"pending_peers,omitempty"`
ActivePeers int `json:"active_peers,omitempty"`
ConnectedSeeders int `json:"connected_seeders,omitempty"`
HalfOpenPeers int `json:"half_open_peers,omitempty"`
BytesWritten int64 `json:"bytes_written,omitempty"`
BytesWrittenData int64 `json:"bytes_written_data,omitempty"`
BytesRead int64 `json:"bytes_read,omitempty"`
BytesReadData int64 `json:"bytes_read_data,omitempty"`
BytesReadUsefulData int64 `json:"bytes_read_useful_data,omitempty"`
ChunksWritten int64 `json:"chunks_written,omitempty"`
ChunksRead int64 `json:"chunks_read,omitempty"`
ChunksReadUseful int64 `json:"chunks_read_useful,omitempty"`
ChunksReadWasted int64 `json:"chunks_read_wasted,omitempty"`
PiecesDirtiedGood int64 `json:"pieces_dirtied_good,omitempty"`
PiecesDirtiedBad int64 `json:"pieces_dirtied_bad,omitempty"`
FileStats []TorrentFileStat `json:"file_stats,omitempty"`
}
type TorrentFileStat struct {
Id int `json:"id,omitempty"`
Path string `json:"path,omitempty"`
Length int64 `json:"length,omitempty"`
}
func (t *Torrent) Stats() TorrentStats {
t.muTorrent.Lock()
defer t.muTorrent.Unlock()
st := TorrentStats{}
st.Name = t.Name()
st.Hash = t.hash.HexString()
st.TorrentStatus = t.Status
st.TorrentStatusString = t.Status.String()
if t.Torrent != nil {
st.LoadedSize = t.Torrent.BytesCompleted()
st.TorrentSize = t.Length()
st.PreloadedBytes = t.PreloadedBytes
st.PreloadSize = t.PreloadSize
st.DownloadSpeed = t.DownloadSpeed
st.UploadSpeed = t.UploadSpeed
tst := t.Torrent.Stats()
st.BytesWritten = tst.BytesWritten.Int64()
st.BytesWrittenData = tst.BytesWrittenData.Int64()
st.BytesRead = tst.BytesRead.Int64()
st.BytesReadData = tst.BytesReadData.Int64()
st.BytesReadUsefulData = tst.BytesReadUsefulData.Int64()
st.ChunksWritten = tst.ChunksWritten.Int64()
st.ChunksRead = tst.ChunksRead.Int64()
st.ChunksReadUseful = tst.ChunksReadUseful.Int64()
st.ChunksReadWasted = tst.ChunksReadWasted.Int64()
st.PiecesDirtiedGood = tst.PiecesDirtiedGood.Int64()
st.PiecesDirtiedBad = tst.PiecesDirtiedBad.Int64()
st.TotalPeers = tst.TotalPeers
st.PendingPeers = tst.PendingPeers
st.ActivePeers = tst.ActivePeers
st.ConnectedSeeders = tst.ConnectedSeeders
st.HalfOpenPeers = tst.HalfOpenPeers
files := t.Files()
sort.Slice(files, func(i, j int) bool {
return files[i].Path() < files[j].Path()
})
for i, f := range files {
st.FileStats = append(st.FileStats, TorrentFileStat{
Id: i,
Path: f.Path(),
Length: f.Length(),
})
}
}
return st
}

View File

@@ -0,0 +1,74 @@
package state
type TorrentStatus int
func (t TorrentStatus) String() string {
switch t {
case TorrentAdded:
return "Torrent added"
case TorrentGettingInfo:
return "Torrent getting info"
case TorrentPreload:
return "Torrent preload"
case TorrentWorking:
return "Torrent working"
case TorrentClosed:
return "Torrent closed"
case TorrentInDB:
return "Torrent in db"
default:
return "Torrent unknown status"
}
}
const (
TorrentAdded = TorrentStatus(iota)
TorrentGettingInfo
TorrentPreload
TorrentWorking
TorrentClosed
TorrentInDB
)
type TorrentStats struct {
Name string `json:"name,omitempty"`
Hash string `json:"hash,omitempty"`
TorrentStatus TorrentStatus `json:"torrent_status,omitempty"`
TorrentStatusString string `json:"torrent_status_string,omitempty"`
LoadedSize int64 `json:"loaded_size,omitempty"`
TorrentSize int64 `json:"torrent_size,omitempty"`
PreloadedBytes int64 `json:"preloaded_bytes,omitempty"`
PreloadSize int64 `json:"preload_size,omitempty"`
DownloadSpeed float64 `json:"download_speed,omitempty"`
UploadSpeed float64 `json:"upload_speed,omitempty"`
TotalPeers int `json:"total_peers,omitempty"`
PendingPeers int `json:"pending_peers,omitempty"`
ActivePeers int `json:"active_peers,omitempty"`
ConnectedSeeders int `json:"connected_seeders,omitempty"`
HalfOpenPeers int `json:"half_open_peers,omitempty"`
BytesWritten int64 `json:"bytes_written,omitempty"`
BytesWrittenData int64 `json:"bytes_written_data,omitempty"`
BytesRead int64 `json:"bytes_read,omitempty"`
BytesReadData int64 `json:"bytes_read_data,omitempty"`
BytesReadUsefulData int64 `json:"bytes_read_useful_data,omitempty"`
ChunksWritten int64 `json:"chunks_written,omitempty"`
ChunksRead int64 `json:"chunks_read,omitempty"`
ChunksReadUseful int64 `json:"chunks_read_useful,omitempty"`
ChunksReadWasted int64 `json:"chunks_read_wasted,omitempty"`
PiecesDirtiedGood int64 `json:"pieces_dirtied_good,omitempty"`
PiecesDirtiedBad int64 `json:"pieces_dirtied_bad,omitempty"`
FileStats []TorrentFileStat `json:"file_stats,omitempty"`
}
type TorrentFileStat struct {
Id int `json:"id,omitempty"`
Path string `json:"path,omitempty"`
Length int64 `json:"length,omitempty"`
}

View File

@@ -1,11 +1,11 @@
package torrstor
import (
"log"
"sort"
"sync"
"github.com/anacrolix/torrent"
"server/log"
"server/settings"
"server/torr/utils"
@@ -52,7 +52,7 @@ func NewCache(capacity int64, storage *Storage) *Cache {
}
func (c *Cache) Init(info *metainfo.Info, hash metainfo.Hash) {
log.Println("Create cache for:", info.Name)
log.TLogln("Create cache for:", info.Name)
if c.capacity == 0 {
c.capacity = info.PieceLength * 6
}
@@ -89,7 +89,7 @@ func (c *Cache) Piece(m metainfo.Piece) storage.PieceImpl {
func (c *Cache) Close() error {
c.isRemove = false
log.Println("Close cache for:", c.hash)
log.TLogln("Close cache for:", c.hash)
if _, ok := c.s.caches[c.hash]; ok {
delete(c.s.caches, c.hash)
}

View File

@@ -2,11 +2,13 @@ package torr
import (
"io"
"log"
"sort"
"sync"
"time"
"server/log"
"server/settings"
"server/torr/state"
"server/torr/utils"
utils2 "server/utils"
@@ -16,43 +18,13 @@ import (
"github.com/anacrolix/torrent/metainfo"
)
type TorrentStatus int
func (t TorrentStatus) String() string {
switch t {
case TorrentAdded:
return "Torrent added"
case TorrentGettingInfo:
return "Torrent getting info"
case TorrentPreload:
return "Torrent preload"
case TorrentWorking:
return "Torrent working"
case TorrentClosed:
return "Torrent closed"
case TorrentInDB:
return "Torrent in db"
default:
return "Torrent unknown status"
}
}
const (
TorrentAdded = TorrentStatus(iota)
TorrentGettingInfo
TorrentPreload
TorrentWorking
TorrentClosed
TorrentInDB
)
type Torrent struct {
///// info for db
Title string
Poster string
*torrent.TorrentSpec
Status TorrentStatus
Status state.TorrentStatus
/////
*torrent.Torrent
@@ -103,7 +75,7 @@ func NewTorrent(spec *torrent.TorrentSpec, bt *BTServer) (*Torrent, error) {
torr := new(Torrent)
torr.Torrent = goTorrent
torr.Status = TorrentAdded
torr.Status = state.TorrentAdded
torr.lastTimeSpeed = time.Now()
torr.bt = bt
torr.closed = goTorrent.Closed()
@@ -135,12 +107,12 @@ func (t *Torrent) WaitInfo() bool {
}
func (t *Torrent) GotInfo() bool {
if t.Status == TorrentClosed {
if t.Status == state.TorrentClosed {
return false
}
t.Status = TorrentGettingInfo
t.Status = state.TorrentGettingInfo
if t.WaitInfo() {
t.Status = TorrentWorking
t.Status = state.TorrentWorking
t.expiredTime = time.Now().Add(time.Minute * 5)
return true
} else {
@@ -166,6 +138,7 @@ func (t *Torrent) watch() {
func (t *Torrent) progressEvent() {
if t.expired() {
log.TLogln("Torrent close by timeout", t.Torrent.InfoHash().HexString())
t.drop()
return
}
@@ -207,7 +180,7 @@ func (t *Torrent) updateRA() {
}
func (t *Torrent) expired() bool {
return t.cache.ReadersLen() == 0 && t.expiredTime.Before(time.Now()) && (t.Status == TorrentWorking || t.Status == TorrentClosed)
return t.cache.ReadersLen() == 0 && t.expiredTime.Before(time.Now()) && (t.Status == state.TorrentWorking || t.Status == state.TorrentClosed)
}
func (t *Torrent) Files() []*torrent.File {
@@ -230,7 +203,7 @@ func (t *Torrent) Length() int64 {
}
func (t *Torrent) NewReader(file *torrent.File, readahead int64) *Reader {
if t.Status == TorrentClosed {
if t.Status == state.TorrentClosed {
return nil
}
reader := NewReader(t, file, readahead)
@@ -252,14 +225,14 @@ func (t *Torrent) Preload(index int, size int64) {
return
}
if t.Status == TorrentGettingInfo {
if t.Status == state.TorrentGettingInfo {
t.WaitInfo()
// wait change status
time.Sleep(100 * time.Millisecond)
}
t.muTorrent.Lock()
if t.Status != TorrentWorking {
if t.Status != state.TorrentWorking {
t.muTorrent.Unlock()
return
}
@@ -271,12 +244,12 @@ func (t *Torrent) Preload(index int, size int64) {
t.muTorrent.Unlock()
return
}
t.Status = TorrentPreload
t.Status = state.TorrentPreload
t.muTorrent.Unlock()
defer func() {
if t.Status == TorrentPreload {
t.Status = TorrentWorking
if t.Status == state.TorrentPreload {
t.Status = state.TorrentWorking
}
}()
@@ -321,10 +294,10 @@ func (t *Torrent) Preload(index int, size int64) {
t.PreloadSize = size
var lastSize int64 = 0
errCount := 0
for t.Status == TorrentPreload {
for t.Status == state.TorrentPreload {
t.expiredTime = time.Now().Add(time.Minute * 5)
t.PreloadedBytes = t.Torrent.BytesCompleted()
log.Println("Preload:", file.Torrent().InfoHash().HexString(), utils2.Format(float64(t.PreloadedBytes)), "/", utils2.Format(float64(t.PreloadSize)), "Speed:", utils2.Format(t.DownloadSpeed), "Peers:[", t.Torrent.Stats().ConnectedSeeders, "]", t.Torrent.Stats().ActivePeers, "/", t.Torrent.Stats().TotalPeers)
log.TLogln("Preload:", file.Torrent().InfoHash().HexString(), utils2.Format(float64(t.PreloadedBytes)), "/", utils2.Format(float64(t.PreloadSize)), "Speed:", utils2.Format(t.DownloadSpeed), "Peers:[", t.Torrent.Stats().ConnectedSeeders, "]", t.Torrent.Stats().ActivePeers, "/", t.Torrent.Stats().TotalPeers)
if t.PreloadedBytes >= t.PreloadSize {
return
}
@@ -352,7 +325,7 @@ func (t *Torrent) drop() {
}
func (t *Torrent) Close() {
t.Status = TorrentClosed
t.Status = state.TorrentClosed
t.bt.mu.Lock()
defer t.bt.mu.Unlock()
@@ -362,3 +335,59 @@ func (t *Torrent) Close() {
t.drop()
}
func (t *Torrent) Stats() *state.TorrentStats {
t.muTorrent.Lock()
defer t.muTorrent.Unlock()
st := new(state.TorrentStats)
st.TorrentStatus = t.Status
st.TorrentStatusString = t.Status.String()
if t.TorrentSpec != nil {
st.Hash = t.TorrentSpec.InfoHash.HexString()
}
if t.Torrent != nil {
st.Name = t.Torrent.Name()
st.Hash = t.Torrent.InfoHash().HexString()
st.LoadedSize = t.Torrent.BytesCompleted()
st.TorrentSize = t.Length()
st.PreloadedBytes = t.PreloadedBytes
st.PreloadSize = t.PreloadSize
st.DownloadSpeed = t.DownloadSpeed
st.UploadSpeed = t.UploadSpeed
tst := t.Torrent.Stats()
st.BytesWritten = tst.BytesWritten.Int64()
st.BytesWrittenData = tst.BytesWrittenData.Int64()
st.BytesRead = tst.BytesRead.Int64()
st.BytesReadData = tst.BytesReadData.Int64()
st.BytesReadUsefulData = tst.BytesReadUsefulData.Int64()
st.ChunksWritten = tst.ChunksWritten.Int64()
st.ChunksRead = tst.ChunksRead.Int64()
st.ChunksReadUseful = tst.ChunksReadUseful.Int64()
st.ChunksReadWasted = tst.ChunksReadWasted.Int64()
st.PiecesDirtiedGood = tst.PiecesDirtiedGood.Int64()
st.PiecesDirtiedBad = tst.PiecesDirtiedBad.Int64()
st.TotalPeers = tst.TotalPeers
st.PendingPeers = tst.PendingPeers
st.ActivePeers = tst.ActivePeers
st.ConnectedSeeders = tst.ConnectedSeeders
st.HalfOpenPeers = tst.HalfOpenPeers
files := t.Files()
sort.Slice(files, func(i, j int) bool {
return files[i].Path() < files[j].Path()
})
for i, f := range files {
st.FileStats = append(st.FileStats, state.TorrentFileStat{
Id: i,
Path: f.Path(),
Length: f.Length(),
})
}
}
return st
}