storj.io/uplink@v1.13.0/private/storage/streams/pieceupload/upload.go (about) 1 // Copyright (C) 2023 Storj Labs, Inc. 2 // See LICENSE for copying information. 3 4 package pieceupload 5 6 import ( 7 "context" 8 "fmt" 9 "io" 10 11 "github.com/spacemonkeygo/monkit/v3" 12 13 "storj.io/common/pb" 14 "storj.io/common/storj" 15 "storj.io/uplink/private/testuplink" 16 ) 17 18 var mon = monkit.Package() 19 20 // PiecePutter puts pieces. 21 type PiecePutter interface { 22 // PutPiece puts a piece using the given limit and private key. The 23 // operation can be cancelled using the longTailCtx or uploadCtx is 24 // cancelled. 25 PutPiece(longTailCtx, uploadCtx context.Context, limit *pb.AddressedOrderLimit, privateKey storj.PiecePrivateKey, data io.ReadCloser) (hash *pb.PieceHash, deprecated *struct{}, err error) 26 } 27 28 // UploadOne uploads one piece from the manager using the given private key. If 29 // it fails, it will attempt to upload another until either the upload context, 30 // or the long tail context is cancelled. 31 func UploadOne(longTailCtx, uploadCtx context.Context, manager *Manager, putter PiecePutter, privateKey storj.PiecePrivateKey) (_ bool, err error) { 32 defer mon.Task()(&longTailCtx)(&err) 33 34 // If the long tail context is cancelled, then return a nil error. 35 defer func() { 36 if longTailCtx.Err() != nil { 37 err = nil 38 } 39 }() 40 41 for { 42 piece, limit, done, err := manager.NextPiece(longTailCtx) 43 if err != nil { 44 return false, err 45 } 46 47 var pieceID string 48 if limit.Limit != nil { 49 pieceID = limit.Limit.PieceId.String() 50 } 51 52 var address, noise string 53 if limit.StorageNodeAddress != nil { 54 address = fmt.Sprintf("%-21s", limit.StorageNodeAddress.Address) 55 noise = fmt.Sprintf("%-5t", limit.StorageNodeAddress.NoiseInfo != nil) 56 } 57 58 logCtx := testuplink.WithLogWriterContext(uploadCtx, 59 "piece_id", pieceID, 60 "address", address, 61 "noise", noise, 62 ) 63 64 testuplink.Log(logCtx, "Uploading piece...") 65 hash, _, err := putter.PutPiece(longTailCtx, uploadCtx, limit, privateKey, io.NopCloser(piece)) 66 testuplink.Log(logCtx, "Done uploading piece. err:", err) 67 done(hash, err == nil) 68 if err == nil { 69 return true, nil 70 } 71 72 if err := uploadCtx.Err(); err != nil { 73 return false, err 74 } 75 76 if longTailCtx.Err() != nil { 77 // If this context is done but the uploadCtx context isn't, then the 78 // download was cancelled for long tail optimization purposes. This 79 // is expected. Return that there was no error but that the upload 80 // did not complete. 81 return false, nil 82 } 83 } 84 }