package downloader
import (
"io"
"sync"
"golang.org/x/sync/singleflight"
"github.com/gotd/td/bin"
"github.com/gotd/td/tg"
)
type cdn struct {
provider CDNProvider
client Client
pool *bin .Pool
retryHandler RetryHandler
master master
max int64
verify bool
stateMux sync .RWMutex
refreshMux sync .Mutex
clientMux sync .Mutex
hashesMux sync .RWMutex
windowsMux sync .Mutex
windowsLoad singleflight .Group
mode cdnMode
redirect *tg .UploadFileCDNRedirect
cdn CDN
closer io .Closer
clientDC int
rev uint64
hashes map [int64 ]tg .FileHash
hashOffsets []int64
windows map [int64 ][]byte
windowsFIFO []int64
}
var _ schema = (*cdn )(nil )
type cdnMode uint8
const (
modeMaster cdnMode = iota
modeCDN
)
const maxVerifiedWindowCache = 16
func newCDNSchema (
masterSchema master ,
provider CDNProvider ,
pool *bin .Pool ,
max int64 ,
verifyCDNInline bool ,
retryHandler RetryHandler ,
) *cdn {
if max < 1 {
max = 1
}
return &cdn {
provider : provider ,
client : masterSchema .client ,
pool : pool ,
retryHandler : retryHandler ,
master : masterSchema ,
max : max ,
verify : verifyCDNInline ,
mode : modeMaster ,
}
}
func (c *cdn ) reportRetry (operation string , attempt int , err error ) {
if attempt < 1 || err == nil || c .retryHandler == nil {
return
}
c .retryHandler (RetryEvent {
Operation : operation ,
Attempt : attempt ,
Err : err ,
})
}
func (c *cdn ) Close () error {
c .stateMux .Lock ()
closer := c .closer
c .cdn = nil
c .closer = nil
c .clientDC = 0
c .stateMux .Unlock ()
if closer != nil {
return closer .Close ()
}
return nil
}
func (c *cdn ) closeClient () {
c .stateMux .Lock ()
closer := c .closer
c .cdn = nil
c .closer = nil
c .clientDC = 0
c .stateMux .Unlock ()
if closer != nil {
_ = closer .Close ()
}
}
func (c *cdn ) snapshot () (mode cdnMode , redirect *tg .UploadFileCDNRedirect , rev uint64 ) {
c .stateMux .RLock ()
defer c .stateMux .RUnlock ()
return c .mode , c .redirect , c .rev
}
func (c *cdn ) setRedirect (redirect *tg .UploadFileCDNRedirect ) {
c .stateMux .Lock ()
c .mode = modeCDN
c .redirect = redirect
c .rev ++
c .stateMux .Unlock ()
c .resetHashes ()
c .resetWindows ()
if redirect != nil {
c .cacheHashes (redirect .FileHashes )
}
}
func (c *cdn ) setMaster () {
c .stateMux .Lock ()
c .mode = modeMaster
c .redirect = nil
c .rev ++
c .stateMux .Unlock ()
c .resetHashes ()
c .resetWindows ()
}
The pages are generated with Golds v0.8.4 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .