@@ -169,89 +169,91 @@ func (s *streamTask) writeToPipe(firstPiece *PieceInfo, pw *io.PipeWriter) {
169169 }()
170170 var (
171171 desired int32
172- cur * PieceInfo
173- wrote int64
172+ piece * PieceInfo
174173 err error
175- cache = make (map [int32 ]bool )
176174 )
177- // update first piece to cache and check cur with desired
178- cache [firstPiece .Num ] = true
179- cur = firstPiece
175+ piece = firstPiece
180176 for {
181- if desired == cur .Num {
182- for {
183- delete (cache , desired )
184- _ , span := tracer .Start (s .ctx , config .SpanWriteBackPiece )
185- span .SetAttributes (config .AttributePiece .Int (int (desired )))
186- wrote , err = s .writeOnePiece (pw , desired )
187- if err != nil {
188- span .RecordError (err )
189- span .End ()
190- s .Errorf ("write to pipe error: %s" , err )
191- _ = pw .CloseWithError (err )
192- return
193- }
194- span .SetAttributes (config .AttributePieceSize .Int (int (wrote )))
195- s .Debugf ("wrote piece %d to pipe, size %d" , desired , wrote )
196- span .End ()
197- desired ++
198- cached := cache [desired ]
199- if ! cached {
200- break
201- }
202- }
203- } else {
204- // not desired piece, cache it
205- cache [cur .Num ] = true
206- if cur .Num < desired {
207- s .Warnf ("piece number should be equal or greater than %d, received piece number: %d" , desired , cur .Num )
177+ if desired == piece .Num || desired <= piece .OrderedNum {
178+ desired , err = s .writeOrderedPieces (desired , piece .OrderedNum , pw )
179+ if err != nil {
180+ return
208181 }
209182 }
210183
211184 select {
212185 case <- s .ctx .Done ():
213- s .Errorf ("context done due to: %s" , s .ctx .Err ())
214- s .span .RecordError (s .ctx .Err ())
215- if err = pw .CloseWithError (s .ctx .Err ()); err != nil {
216- s .Errorf ("CloseWithError failed: %s" , err )
217- }
218- return
219- case cur = <- s .pieceCh :
220- // FIXME check missing piece for non-block broker channel
186+ err = fmt .Errorf ("context done due to: %s" , s .ctx .Err ())
187+ s .closeWithError (pw , err )
188+ break
189+ case piece = <- s .pieceCh :
221190 continue
222191 case <- s .peerTaskConductor .failCh :
223- ptError : = fmt .Errorf ("context done due to peer task fail: %d/%s" ,
192+ err = fmt .Errorf ("context done due to peer task fail: %d/%s" ,
224193 s .peerTaskConductor .failedCode , s .peerTaskConductor .failedReason )
225- s .Error (ptError .Error ())
226- s .span .RecordError (ptError )
227- if err = pw .CloseWithError (ptError ); err != nil {
228- s .Errorf ("CloseWithError failed: %s" , err )
229- }
230- return
194+ s .closeWithError (pw , err )
195+ break
231196 case <- s .peerTaskConductor .successCh :
232- for {
233- // all data wrote to local storage, and all data wrote to pipe write
234- if s .peerTaskConductor .readyPieces .Settled () == desired {
235- s .Debugf ("all %d pieces wrote to pipe" , desired )
236- pw .Close ()
237- return
238- }
239- _ , span := tracer .Start (s .ctx , config .SpanWriteBackPiece )
240- span .SetAttributes (config .AttributePiece .Int (int (desired )))
241- wrote , err = s .writeOnePiece (pw , desired )
242- if err != nil {
243- span .RecordError (err )
244- span .End ()
245- s .span .RecordError (err )
246- s .Errorf ("write to pipe error: %s" , err )
247- _ = pw .CloseWithError (err )
248- return
249- }
250- span .SetAttributes (config .AttributePieceSize .Int (int (wrote )))
251- span .End ()
252- s .Debugf ("wrote piece %d to pipe, size %d" , desired , wrote )
253- desired ++
254- }
197+ s .writeRemainingPieces (desired , pw )
198+ break
255199 }
256200 }
257201}
202+
203+ func (s * streamTask ) writeOrderedPieces (desired , orderedNum int32 , pw * io.PipeWriter ) (int32 , error ) {
204+ for {
205+ _ , span := tracer .Start (s .ctx , config .SpanWriteBackPiece )
206+ span .SetAttributes (config .AttributePiece .Int (int (desired )))
207+ wrote , err := s .writeOnePiece (pw , desired )
208+ if err != nil {
209+ span .RecordError (err )
210+ span .End ()
211+ s .Errorf ("write to pipe error: %s" , err )
212+ _ = pw .CloseWithError (err )
213+ return desired , err
214+ }
215+ span .SetAttributes (config .AttributePieceSize .Int (int (wrote )))
216+ s .Debugf ("wrote piece %d to pipe, size %d" , desired , wrote )
217+ span .End ()
218+
219+ desired ++
220+ if desired > orderedNum {
221+ break
222+ }
223+ }
224+ return desired , nil
225+ }
226+
227+ func (s * streamTask ) writeRemainingPieces (desired int32 , pw * io.PipeWriter ) {
228+ for {
229+ // all data wrote to local storage, and all data wrote to pipe write
230+ if s .peerTaskConductor .readyPieces .Settled () == desired {
231+ s .Debugf ("all %d pieces wrote to pipe" , desired )
232+ pw .Close ()
233+ return
234+ }
235+ _ , span := tracer .Start (s .ctx , config .SpanWriteBackPiece )
236+ span .SetAttributes (config .AttributePiece .Int (int (desired )))
237+ wrote , err := s .writeOnePiece (pw , desired )
238+ if err != nil {
239+ span .RecordError (err )
240+ span .End ()
241+ s .span .RecordError (err )
242+ s .Errorf ("write to pipe error: %s" , err )
243+ _ = pw .CloseWithError (err )
244+ return
245+ }
246+ span .SetAttributes (config .AttributePieceSize .Int (int (wrote )))
247+ span .End ()
248+ s .Debugf ("wrote piece %d to pipe, size %d" , desired , wrote )
249+ desired ++
250+ }
251+ }
252+
253+ func (s * streamTask ) closeWithError (pw * io.PipeWriter , err error ) {
254+ s .Error (err )
255+ s .span .RecordError (err )
256+ if err = pw .CloseWithError (err ); err != nil {
257+ s .Errorf ("CloseWithError failed: %s" , err )
258+ }
259+ }
0 commit comments