@@ -277,10 +277,7 @@ func (s *streamPeerTask) Start(ctx context.Context) (io.ReadCloser, map[string]s
277
277
firstPiece = first
278
278
}
279
279
280
- pr , pw := io .Pipe ()
281
280
attr := map [string ]string {}
282
- var readCloser io.ReadCloser = pr
283
- var writer io.Writer = pw
284
281
if s .contentLength .Load () != - 1 {
285
282
attr [headers .ContentLength ] = fmt .Sprintf ("%d" , s .contentLength .Load ())
286
283
} else {
@@ -289,89 +286,9 @@ func (s *streamPeerTask) Start(ctx context.Context) (io.ReadCloser, map[string]s
289
286
attr [config .HeaderDragonflyTask ] = s .taskID
290
287
attr [config .HeaderDragonflyPeer ] = s .peerID
291
288
292
- go func (first int32 ) {
293
- defer func () {
294
- s .cancel ()
295
- s .span .End ()
296
- }()
297
- var (
298
- desired int32
299
- cur int32
300
- wrote int64
301
- err error
302
- //ok bool
303
- cache = make (map [int32 ]bool )
304
- )
305
- // update first piece to cache and check cur with desired
306
- cache [first ] = true
307
- cur = first
308
- for {
309
- if desired == cur {
310
- for {
311
- delete (cache , desired )
312
- _ , span := tracer .Start (s .ctx , config .SpanWriteBackPiece )
313
- span .SetAttributes (config .AttributePiece .Int (int (desired )))
314
- wrote , err = s .writeTo (writer , desired )
315
- if err != nil {
316
- span .RecordError (err )
317
- span .End ()
318
- s .Errorf ("write to pipe error: %s" , err )
319
- _ = pw .CloseWithError (err )
320
- return
321
- }
322
- span .SetAttributes (config .AttributePieceSize .Int (int (wrote )))
323
- s .Debugf ("wrote piece %d to pipe, size %d" , desired , wrote )
324
- span .End ()
325
- desired ++
326
- cached := cache [desired ]
327
- if ! cached {
328
- break
329
- }
330
- }
331
- } else {
332
- // not desired piece, cache it
333
- cache [cur ] = true
334
- if cur < desired {
335
- s .Warnf ("piece number should be equal or greater than %d, received piece number: %d" , desired , cur )
336
- }
337
- }
338
-
339
- select {
340
- case <- s .ctx .Done ():
341
- s .Errorf ("ctx.PeerTaskDone due to: %s" , s .ctx .Err ())
342
- s .span .RecordError (s .ctx .Err ())
343
- if err := pw .CloseWithError (s .ctx .Err ()); err != nil {
344
- s .Errorf ("CloseWithError failed: %s" , err )
345
- }
346
- return
347
- case <- s .streamDone :
348
- for {
349
- // all data wrote to local storage, and all data wrote to pipe write
350
- if s .readyPieces .Settled () == desired {
351
- pw .Close ()
352
- return
353
- }
354
- _ , span := tracer .Start (s .ctx , config .SpanWriteBackPiece )
355
- span .SetAttributes (config .AttributePiece .Int (int (desired )))
356
- wrote , err = s .writeTo (pw , desired )
357
- if err != nil {
358
- span .RecordError (err )
359
- span .End ()
360
- s .span .RecordError (err )
361
- s .Errorf ("write to pipe error: %s" , err )
362
- _ = pw .CloseWithError (err )
363
- return
364
- }
365
- span .SetAttributes (config .AttributePieceSize .Int (int (wrote )))
366
- span .End ()
367
- s .Debugf ("wrote piece %d to pipe, size %d" , desired , wrote )
368
- desired ++
369
- }
370
- case cur = <- s .successPieceCh :
371
- continue
372
- }
373
- }
374
- }(firstPiece )
289
+ pr , pw := io .Pipe ()
290
+ var readCloser io.ReadCloser = pr
291
+ go s .writeToPipe (firstPiece , pw )
375
292
376
293
return readCloser , attr , nil
377
294
}
@@ -428,7 +345,7 @@ func (s *streamPeerTask) SetTotalPieces(i int32) {
428
345
s .totalPiece = i
429
346
}
430
347
431
- func (s * streamPeerTask ) writeTo (w io.Writer , pieceNum int32 ) (int64 , error ) {
348
+ func (s * streamPeerTask ) writeOnePiece (w io.Writer , pieceNum int32 ) (int64 , error ) {
432
349
pr , pc , err := s .pieceManager .ReadPiece (s .ctx , & storage.ReadPieceRequest {
433
350
PeerTaskMetaData : storage.PeerTaskMetaData {
434
351
PeerID : s .peerID ,
@@ -476,3 +393,87 @@ func (s *streamPeerTask) backSource() {
476
393
_ = s .finish ()
477
394
return
478
395
}
396
+
397
+ func (s * streamPeerTask ) writeToPipe (firstPiece int32 , pw * io.PipeWriter ) {
398
+ defer func () {
399
+ s .cancel ()
400
+ s .span .End ()
401
+ }()
402
+ var (
403
+ desired int32
404
+ cur int32
405
+ wrote int64
406
+ err error
407
+ cache = make (map [int32 ]bool )
408
+ )
409
+ // update first piece to cache and check cur with desired
410
+ cache [firstPiece ] = true
411
+ cur = firstPiece
412
+ for {
413
+ if desired == cur {
414
+ for {
415
+ delete (cache , desired )
416
+ _ , span := tracer .Start (s .ctx , config .SpanWriteBackPiece )
417
+ span .SetAttributes (config .AttributePiece .Int (int (desired )))
418
+ wrote , err = s .writeOnePiece (pw , desired )
419
+ if err != nil {
420
+ span .RecordError (err )
421
+ span .End ()
422
+ s .Errorf ("write to pipe error: %s" , err )
423
+ _ = pw .CloseWithError (err )
424
+ return
425
+ }
426
+ span .SetAttributes (config .AttributePieceSize .Int (int (wrote )))
427
+ s .Debugf ("wrote piece %d to pipe, size %d" , desired , wrote )
428
+ span .End ()
429
+ desired ++
430
+ cached := cache [desired ]
431
+ if ! cached {
432
+ break
433
+ }
434
+ }
435
+ } else {
436
+ // not desired piece, cache it
437
+ cache [cur ] = true
438
+ if cur < desired {
439
+ s .Warnf ("piece number should be equal or greater than %d, received piece number: %d" , desired , cur )
440
+ }
441
+ }
442
+
443
+ select {
444
+ case <- s .ctx .Done ():
445
+ s .Errorf ("ctx.PeerTaskDone due to: %s" , s .ctx .Err ())
446
+ s .span .RecordError (s .ctx .Err ())
447
+ if err := pw .CloseWithError (s .ctx .Err ()); err != nil {
448
+ s .Errorf ("CloseWithError failed: %s" , err )
449
+ }
450
+ return
451
+ case <- s .streamDone :
452
+ for {
453
+ // all data wrote to local storage, and all data wrote to pipe write
454
+ if s .readyPieces .Settled () == desired {
455
+ s .Debugf ("all %d pieces wrote to pipe" , desired )
456
+ pw .Close ()
457
+ return
458
+ }
459
+ _ , span := tracer .Start (s .ctx , config .SpanWriteBackPiece )
460
+ span .SetAttributes (config .AttributePiece .Int (int (desired )))
461
+ wrote , err = s .writeOnePiece (pw , desired )
462
+ if err != nil {
463
+ span .RecordError (err )
464
+ span .End ()
465
+ s .span .RecordError (err )
466
+ s .Errorf ("write to pipe error: %s" , err )
467
+ _ = pw .CloseWithError (err )
468
+ return
469
+ }
470
+ span .SetAttributes (config .AttributePieceSize .Int (int (wrote )))
471
+ span .End ()
472
+ s .Debugf ("wrote piece %d to pipe, size %d" , desired , wrote )
473
+ desired ++
474
+ }
475
+ case cur = <- s .successPieceCh :
476
+ continue
477
+ }
478
+ }
479
+ }
0 commit comments