userOnWriteChunkErr func(error)
closed chansync.SetOnce
+ onClose []func()
infoHash metainfo.Hash
pieces []Piece
err = errors.New("already closed")
return
}
+ for _, f := range t.onClose {
+ f()
+ }
if t.storage != nil {
wg.Add(1)
go func() {
}
func (t *Torrent) startWebsocketAnnouncer(u url.URL) torrentTrackerAnnouncer {
- wtc, release := t.cl.websocketTrackers.Get(u.String())
- go func() {
- <-t.closed.Done()
- release()
- }()
+ wtc, release := t.cl.websocketTrackers.Get(u.String(), t.infoHash)
+ // This needs to run before the Torrent is dropped from the Client, to prevent a new webtorrent.TrackerClient for
+ // the same info hash before the old one is cleaned up.
+ t.onClose = append(t.onClose, release)
wst := websocketTrackerStatus{u, wtc}
go func() {
err := wtc.Announce(tracker.Started, t.infoHash)
tc.outboundOffers = nil
}
+func (tc *TrackerClient) CloseOffersForInfohash(infoHash [20]byte) {
+ tc.mu.Lock()
+ defer tc.mu.Unlock()
+ for key, offer := range tc.outboundOffers {
+ if offer.infoHash == infoHash {
+ offer.peerConnection.Close()
+ delete(tc.outboundOffers, key)
+ }
+ }
+}
+
func (tc *TrackerClient) Announce(event tracker.AnnounceEvent, infoHash [20]byte) error {
metrics.Add("outbound announces", 1)
var randOfferId [20]byte
Proxy http.ProxyFunc
}
-func (me *websocketTrackers) Get(url string) (*webtorrent.TrackerClient, func()) {
+func (me *websocketTrackers) Get(url string, infoHash [20]byte) (*webtorrent.TrackerClient, func()) {
me.mu.Lock()
defer me.mu.Unlock()
value, ok := me.clients[url]
return &value.TrackerClient, func() {
me.mu.Lock()
defer me.mu.Unlock()
+ value.TrackerClient.CloseOffersForInfohash(infoHash)
value.refCount--
if value.refCount == 0 {
value.TrackerClient.Close()