better handle context cancellations in the PBDagReader
Good: If a previous read is canceled, we cancel the preloads that the read triggered. Bad: Future reads at that point will fail. This fixes that issue. License: MIT Signed-off-by: Steven Allen <steven@stebalien.com>
Steven Allen committed
Jun 27, 2018 at 17:06 UTC
0344e3e6027c7755678c5bbee18c410dafb1b20d
1 file changed
+19
-2
unixfs/io/pbdagreader.go
+19
-2
@@ -95,10 +95,27 @@ func (dr *PBDagReader) precalcNextBuf(ctx context.Context) error {
95
}
96
97
nxt, err := dr.promises[dr.linkPosition].Get(ctx)
98
- if err != nil {
98
+ dr.promises[dr.linkPosition] = nil
99
+ switch err {
100
+ case nil:
101
+ case context.DeadlineExceeded, context.Canceled:
102
+ err = ctx.Err()
103
+ if err != nil {
104
+ return ctx.Err()
105
+ }
106
+ // In this case, the context used to *preload* the node has been canceled.
107
+ // We need to retry the load with our context and we might as
108
+ // well preload some extra nodes while we're at it.
109
+ dr.preload(ctx, dr.linkPosition)
110
+ nxt, err = dr.promises[dr.linkPosition].Get(ctx)
111
+ dr.promises[dr.linkPosition] = nil
112
+ if err != nil {
113
+ return err
114
+ }
115
+ default:
116
return err
117
}
101
- dr.promises[dr.linkPosition] = nil
118
+
119
dr.linkPosition++
120
121
switch nxt := nxt.(type) {