@@ -7,32 +7,42 @@ import (
7
7
8
8
datatransfer "github.com/filecoin-project/go-data-transfer"
9
9
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
10
+ lotus_dtypes "github.com/filecoin-project/lotus/node/modules/dtypes"
10
11
logging "github.com/ipfs/go-log/v2"
11
12
)
12
13
13
14
var log = logging .Logger ("rtrvlog" )
14
15
15
16
type RetrievalLog struct {
16
- db * RetrievalLogDB
17
- duration time.Duration
18
- ctx context.Context
17
+ db * RetrievalLogDB
18
+ duration time.Duration
19
+ dataTransfer lotus_dtypes.ProviderDataTransfer
20
+ stalledTimeout time.Duration
21
+ ctx context.Context
19
22
20
23
lastUpdateLk sync.Mutex
21
24
lastUpdate map [string ]time.Time
22
25
}
23
26
24
- func NewRetrievalLog (db * RetrievalLogDB , duration time.Duration ) * RetrievalLog {
27
+ func NewRetrievalLog (db * RetrievalLogDB , duration time.Duration , dt lotus_dtypes.ProviderDataTransfer , stalledTimeout time.Duration ) * RetrievalLog {
28
+ if duration < stalledTimeout {
29
+ log .Warnf ("the RetrievalLogDuration (%s) should exceed the StalledRetrievalTimeout (%s)" , duration .String (), stalledTimeout .String ())
30
+ }
31
+
25
32
return & RetrievalLog {
26
- db : db ,
27
- duration : duration ,
28
- lastUpdate : make (map [string ]time.Time ),
33
+ db : db ,
34
+ duration : duration ,
35
+ dataTransfer : dt ,
36
+ stalledTimeout : stalledTimeout ,
37
+ lastUpdate : make (map [string ]time.Time ),
29
38
}
30
39
}
31
40
32
41
func (r * RetrievalLog ) Start (ctx context.Context ) {
33
42
r .ctx = ctx
34
43
go r .gcUpdateMap (ctx )
35
44
go r .gcDatabase (ctx )
45
+ go r .gcRetrievals (ctx )
36
46
}
37
47
38
48
// Called when there is a retrieval ask query
@@ -225,3 +235,34 @@ func (r *RetrievalLog) gcDatabase(ctx context.Context) {
225
235
}
226
236
}
227
237
}
238
+
239
+ // Periodically cancels stalled retrievals older than 30mins
240
+ func (r * RetrievalLog ) gcRetrievals (ctx context.Context ) {
241
+ ticker := time .NewTicker (5 * time .Minute )
242
+ defer ticker .Stop ()
243
+
244
+ for {
245
+ select {
246
+ case <- ctx .Done ():
247
+ return
248
+ case now := <- ticker .C :
249
+ // Get retrievals last updated
250
+ rows , err := r .db .ListLastUpdatedAndOpen (ctx , now .Add (- r .stalledTimeout ))
251
+
252
+ if err != nil {
253
+ log .Errorw ("error fetching open, stalled retrievals" , "err" , err )
254
+ continue
255
+ }
256
+
257
+ for _ , row := range rows {
258
+ chid := datatransfer.ChannelID {Initiator : row .PeerID , Responder : row .LocalPeerID , ID : row .TransferID }
259
+ err := r .dataTransfer .CloseDataTransferChannel (ctx , chid )
260
+ if err != nil {
261
+ log .Errorw ("error canceling retrieval" , "dealID" , row .DealID , "err" , err )
262
+ } else {
263
+ log .Infof ("Canceled retrieval %s, older than %s" , row .DealID , r .stalledTimeout )
264
+ }
265
+ }
266
+ }
267
+ }
268
+ }
0 commit comments