@@ -78,6 +78,7 @@ type Transport struct {
78
78
contextCancelMap map [datatransfer.ChannelID ]cancelRequest
79
79
pending map [datatransfer.ChannelID ]chan struct {}
80
80
requestorCancelledMap map [datatransfer.ChannelID ]struct {}
81
+ channelXferStarted map [datatransfer.ChannelID ]bool
81
82
pendingExtensions map [datatransfer.ChannelID ][]graphsync.ExtensionData
82
83
stores map [datatransfer.ChannelID ]struct {}
83
84
supportedExtensions []graphsync.ExtensionName
@@ -98,6 +99,7 @@ func NewTransport(peerID peer.ID, gs graphsync.GraphExchange, options ...Option)
98
99
pendingExtensions : make (map [datatransfer.ChannelID ][]graphsync.ExtensionData ),
99
100
channelIDMap : make (map [datatransfer.ChannelID ]graphsyncKey ),
100
101
pending : make (map [datatransfer.ChannelID ]chan struct {}),
102
+ channelXferStarted : make (map [datatransfer.ChannelID ]bool ),
101
103
stores : make (map [datatransfer.ChannelID ]struct {}),
102
104
supportedExtensions : defaultSupportedExtensions ,
103
105
}
@@ -149,15 +151,22 @@ func (t *Transport) OpenChannel(ctx context.Context,
149
151
// Relock now that request has been cancelled
150
152
t .dataLock .Lock ()
151
153
}
152
- // Set up the request listeners
154
+
155
+ // Keep track of "pending" channels.
156
+ // The channel is in the "pending" state when we've made a call to
157
+ // Graphsync to open a request, but Graphsync hasn't yet called the
158
+ // outgoing request hook.
153
159
t .pending [channelID ] = make (chan struct {})
154
160
161
+ // Create a cancellable context for the channel so that the graphsync
162
+ // request can be cancelled
155
163
internalCtx , internalCancel := context .WithCancel (ctx )
156
164
cancelRQ := cancelRequest {
157
165
cancel : internalCancel ,
158
166
completed : make (chan struct {}),
159
167
}
160
168
t .contextCancelMap [channelID ] = cancelRQ
169
+
161
170
t .dataLock .Unlock ()
162
171
163
172
// If this is a restart request, the client can send a list of CIDs of
@@ -348,10 +357,10 @@ func (t *Transport) ResumeChannel(ctx context.Context,
348
357
defer t .dataLock .Unlock ()
349
358
350
359
if _ , ok := t .requestorCancelledMap [chid ]; ok {
351
-
352
360
t .pendingExtensions [chid ] = append (t .pendingExtensions [chid ], extensions ... )
353
361
return nil
354
362
}
363
+ t .channelXferStarted [chid ] = true
355
364
return t .gs .UnpauseResponse (gsKey .p , gsKey .requestID , extensions ... )
356
365
}
357
366
@@ -375,10 +384,11 @@ func (t *Transport) CloseChannel(ctx context.Context, chid datatransfer.ChannelI
375
384
return nil
376
385
}
377
386
t .dataLock .Lock ()
378
- if _ , ok := t .requestorCancelledMap [chid ]; ok {
387
+ _ , ok := t .requestorCancelledMap [chid ]
388
+ t .dataLock .Unlock ()
389
+ if ok {
379
390
return nil
380
391
}
381
- t .dataLock .Unlock ()
382
392
return t .gs .CancelResponse (gsKey .p , gsKey .requestID )
383
393
}
384
394
@@ -606,11 +616,26 @@ func (t *Transport) gsReqRecdHook(p peer.ID, request graphsync.RequestData, hook
606
616
return
607
617
}
608
618
619
+ // Check if the callback indicated that the channel should be paused
620
+ // immediately
621
+ paused := false
609
622
if err == datatransfer .ErrPause {
623
+ paused = true
610
624
hookActions .PauseResponse ()
611
625
}
612
626
613
627
t .dataLock .Lock ()
628
+
629
+ // If this is a restart request, and the data transfer still hasn't got
630
+ // out of the paused state (eg because we're still unsealing), start this
631
+ // graphsync response in the paused state.
632
+ hasXferStarted , isRestart := t .channelXferStarted [chid ]
633
+ if isRestart && ! hasXferStarted && ! paused {
634
+ paused = true
635
+ hookActions .PauseResponse ()
636
+ }
637
+ t .channelXferStarted [chid ] = ! paused
638
+
614
639
gsKey := graphsyncKey {request .ID (), p }
615
640
if _ , ok := t .requestorCancelledMap [chid ]; ok {
616
641
delete (t .requestorCancelledMap , chid )
@@ -626,7 +651,9 @@ func (t *Transport) gsReqRecdHook(p peer.ID, request graphsync.RequestData, hook
626
651
if ok {
627
652
hookActions .UsePersistenceOption ("data-transfer-" + chid .String ())
628
653
}
654
+
629
655
t .dataLock .Unlock ()
656
+
630
657
hookActions .ValidateRequest ()
631
658
}
632
659
@@ -695,6 +722,7 @@ func (t *Transport) cleanupChannel(chid datatransfer.ChannelID, gsKey graphsyncK
695
722
delete (t .graphsyncRequestMap , gsKey )
696
723
delete (t .pendingExtensions , chid )
697
724
delete (t .requestorCancelledMap , chid )
725
+ delete (t .channelXferStarted , chid )
698
726
_ , ok := t .stores [chid ]
699
727
if ok {
700
728
opt := "data-transfer-" + chid .String ()
0 commit comments