| @@ -27,11 +27,6 @@ type CreateECPackage struct { | |||||
| redundancy models.ECRedundancyInfo | redundancy models.ECRedundancyInfo | ||||
| } | } | ||||
| type UpdateECPackageContext struct { | |||||
| *UpdatePackageContext | |||||
| ECPacketSize int64 | |||||
| } | |||||
| type CreateECPackageResult struct { | type CreateECPackageResult struct { | ||||
| PackageID int64 | PackageID int64 | ||||
| ObjectResults []ECObjectUploadResult | ObjectResults []ECObjectUploadResult | ||||
| @@ -53,7 +48,7 @@ func NewCreateECPackage(userID int64, bucketID int64, name string, objIter itera | |||||
| } | } | ||||
| } | } | ||||
| func (t *CreateECPackage) Execute(ctx *UpdateECPackageContext) (*CreateECPackageResult, error) { | |||||
| func (t *CreateECPackage) Execute(ctx *UpdatePackageContext) (*CreateECPackageResult, error) { | |||||
| defer t.objectIter.Close() | defer t.objectIter.Close() | ||||
| coorCli, err := globals.CoordinatorMQPool.Acquire() | coorCli, err := globals.CoordinatorMQPool.Acquire() | ||||
| @@ -82,7 +77,7 @@ func (t *CreateECPackage) Execute(ctx *UpdateECPackageContext) (*CreateECPackage | |||||
| defer mutex.Unlock() | defer mutex.Unlock() | ||||
| createPkgResp, err := coorCli.CreatePackage(coormq.NewCreatePackage(t.userID, t.bucketID, t.name, | createPkgResp, err := coorCli.CreatePackage(coormq.NewCreatePackage(t.userID, t.bucketID, t.name, | ||||
| models.NewTypedRedundancyInfo(models.RedundancyRep, t.redundancy))) | |||||
| models.NewTypedRedundancyInfo(t.redundancy))) | |||||
| if err != nil { | if err != nil { | ||||
| return nil, fmt.Errorf("creating package: %w", err) | return nil, fmt.Errorf("creating package: %w", err) | ||||
| } | } | ||||
| @@ -129,7 +124,7 @@ func (t *CreateECPackage) Execute(ctx *UpdateECPackageContext) (*CreateECPackage | |||||
| } | } | ||||
| defer ipfsMutex.Unlock() | defer ipfsMutex.Unlock() | ||||
| rets, err := uploadAndUpdateECPackage(ctx, createPkgResp.PackageID, t.objectIter, uploadNodeInfos, getECResp.Config) | |||||
| rets, err := uploadAndUpdateECPackage(createPkgResp.PackageID, t.objectIter, uploadNodeInfos, t.redundancy, getECResp.Config) | |||||
| if err != nil { | if err != nil { | ||||
| return nil, err | return nil, err | ||||
| } | } | ||||
| @@ -140,7 +135,7 @@ func (t *CreateECPackage) Execute(ctx *UpdateECPackageContext) (*CreateECPackage | |||||
| }, nil | }, nil | ||||
| } | } | ||||
| func uploadAndUpdateECPackage(ctx *UpdateECPackageContext, packageID int64, objectIter iterator.UploadingObjectIterator, uploadNodes []UploadNodeInfo, ec model.Ec) ([]ECObjectUploadResult, error) { | |||||
| func uploadAndUpdateECPackage(packageID int64, objectIter iterator.UploadingObjectIterator, uploadNodes []UploadNodeInfo, ecInfo models.ECRedundancyInfo, ec model.Ec) ([]ECObjectUploadResult, error) { | |||||
| coorCli, err := globals.CoordinatorMQPool.Acquire() | coorCli, err := globals.CoordinatorMQPool.Acquire() | ||||
| if err != nil { | if err != nil { | ||||
| return nil, fmt.Errorf("new coordinator client: %w", err) | return nil, fmt.Errorf("new coordinator client: %w", err) | ||||
| @@ -158,7 +153,7 @@ func uploadAndUpdateECPackage(ctx *UpdateECPackageContext, packageID int64, obje | |||||
| return nil, fmt.Errorf("reading object: %w", err) | return nil, fmt.Errorf("reading object: %w", err) | ||||
| } | } | ||||
| fileHashes, uploadedNodeIDs, err := uploadECObject(ctx, objInfo, uploadNodes, ec) | |||||
| fileHashes, uploadedNodeIDs, err := uploadECObject(objInfo, uploadNodes, ecInfo, ec) | |||||
| uploadRets = append(uploadRets, ECObjectUploadResult{ | uploadRets = append(uploadRets, ECObjectUploadResult{ | ||||
| Info: objInfo, | Info: objInfo, | ||||
| Error: err, | Error: err, | ||||
| @@ -179,7 +174,7 @@ func uploadAndUpdateECPackage(ctx *UpdateECPackageContext, packageID int64, obje | |||||
| } | } | ||||
| // 上传文件 | // 上传文件 | ||||
| func uploadECObject(ctx *UpdateECPackageContext, obj *iterator.IterUploadingObject, uploadNodes []UploadNodeInfo, ec model.Ec) ([]string, []int64, error) { | |||||
| func uploadECObject(obj *iterator.IterUploadingObject, uploadNodes []UploadNodeInfo, ecInfo models.ECRedundancyInfo, ec model.Ec) ([]string, []int64, error) { | |||||
| //生成纠删码的写入节点序列 | //生成纠删码的写入节点序列 | ||||
| nodes := make([]UploadNodeInfo, ec.EcN) | nodes := make([]UploadNodeInfo, ec.EcN) | ||||
| numNodes := len(uploadNodes) | numNodes := len(uploadNodes) | ||||
| @@ -188,7 +183,7 @@ func uploadECObject(ctx *UpdateECPackageContext, obj *iterator.IterUploadingObje | |||||
| nodes[i] = uploadNodes[(startWriteNodeID+i)%numNodes] | nodes[i] = uploadNodes[(startWriteNodeID+i)%numNodes] | ||||
| } | } | ||||
| hashs, err := ecWrite(ctx, obj.File, obj.Size, ec.EcK, ec.EcN, nodes) | |||||
| hashs, err := ecWrite(obj.File, obj.Size, ecInfo.PacketSize, ec.EcK, ec.EcN, nodes) | |||||
| if err != nil { | if err != nil { | ||||
| return nil, nil, fmt.Errorf("EcWrite failed, err: %w", err) | return nil, nil, fmt.Errorf("EcWrite failed, err: %w", err) | ||||
| } | } | ||||
| @@ -213,13 +208,13 @@ func (t *CreateECPackage) chooseUploadNode(nodes []UploadNodeInfo) UploadNodeInf | |||||
| return nodes[rand.Intn(len(nodes))] | return nodes[rand.Intn(len(nodes))] | ||||
| } | } | ||||
| func ecWrite(ctx *UpdateECPackageContext, file io.ReadCloser, fileSize int64, ecK int, ecN int, nodes []UploadNodeInfo) ([]string, error) { | |||||
| func ecWrite(file io.ReadCloser, fileSize int64, packetSize int64, ecK int, ecN int, nodes []UploadNodeInfo) ([]string, error) { | |||||
| // TODO 需要参考RepWrite函数的代码逻辑,做好错误处理 | // TODO 需要参考RepWrite函数的代码逻辑,做好错误处理 | ||||
| //获取文件大小 | //获取文件大小 | ||||
| var coefs = [][]int64{{1, 1, 1}, {1, 2, 3}} //2应替换为ecK,3应替换为ecN | var coefs = [][]int64{{1, 1, 1}, {1, 2, 3}} //2应替换为ecK,3应替换为ecN | ||||
| //计算每个块的packet数 | //计算每个块的packet数 | ||||
| numPacket := (fileSize + int64(ecK)*ctx.ECPacketSize - 1) / (int64(ecK) * ctx.ECPacketSize) | |||||
| numPacket := (fileSize + int64(ecK)*packetSize - 1) / (int64(ecK) * packetSize) | |||||
| //fmt.Println(numPacket) | //fmt.Println(numPacket) | ||||
| //创建channel | //创建channel | ||||
| loadBufs := make([]chan []byte, ecN) | loadBufs := make([]chan []byte, ecN) | ||||
| @@ -232,7 +227,7 @@ func ecWrite(ctx *UpdateECPackageContext, file io.ReadCloser, fileSize int64, ec | |||||
| } | } | ||||
| hashs := make([]string, ecN) | hashs := make([]string, ecN) | ||||
| //正式开始写入 | //正式开始写入 | ||||
| go load(file, loadBufs[:ecN], ecK, numPacket*int64(ecK), ctx.ECPacketSize) //从本地文件系统加载数据 | |||||
| go load(file, loadBufs[:ecN], ecK, numPacket*int64(ecK), packetSize) //从本地文件系统加载数据 | |||||
| go encode(loadBufs[:ecN], encodeBufs[:ecN], ecK, coefs, numPacket) | go encode(loadBufs[:ecN], encodeBufs[:ecN], ecK, coefs, numPacket) | ||||
| var wg sync.WaitGroup | var wg sync.WaitGroup | ||||
| @@ -92,7 +92,7 @@ func (t *CreateRepPackage) Execute(ctx *UpdatePackageContext) (*CreateRepPackage | |||||
| defer mutex.Unlock() | defer mutex.Unlock() | ||||
| createPkgResp, err := coorCli.CreatePackage(coormq.NewCreatePackage(t.userID, t.bucketID, t.name, | createPkgResp, err := coorCli.CreatePackage(coormq.NewCreatePackage(t.userID, t.bucketID, t.name, | ||||
| models.NewTypedRedundancyInfo(models.RedundancyRep, t.redundancy))) | |||||
| models.NewTypedRedundancyInfo(t.redundancy))) | |||||
| if err != nil { | if err != nil { | ||||
| return nil, fmt.Errorf("creating package: %w", err) | return nil, fmt.Errorf("creating package: %w", err) | ||||
| } | } | ||||
| @@ -8,7 +8,6 @@ import ( | |||||
| "gitlink.org.cn/cloudream/common/models" | "gitlink.org.cn/cloudream/common/models" | ||||
| distsvc "gitlink.org.cn/cloudream/common/pkgs/distlock/service" | distsvc "gitlink.org.cn/cloudream/common/pkgs/distlock/service" | ||||
| "gitlink.org.cn/cloudream/common/utils/serder" | |||||
| "gitlink.org.cn/cloudream/storage-common/globals" | "gitlink.org.cn/cloudream/storage-common/globals" | ||||
| "gitlink.org.cn/cloudream/storage-common/pkgs/db/model" | "gitlink.org.cn/cloudream/storage-common/pkgs/db/model" | ||||
| "gitlink.org.cn/cloudream/storage-common/pkgs/iterator" | "gitlink.org.cn/cloudream/storage-common/pkgs/iterator" | ||||
| @@ -22,8 +21,7 @@ type DownloadPackage struct { | |||||
| } | } | ||||
| type DownloadPackageContext struct { | type DownloadPackageContext struct { | ||||
| Distlock *distsvc.Service | |||||
| ECPacketSize int64 | |||||
| Distlock *distsvc.Service | |||||
| } | } | ||||
| func NewDownloadPackage(userID int64, packageID int64, outputPath string) *DownloadPackage { | func NewDownloadPackage(userID int64, packageID int64, outputPath string) *DownloadPackage { | ||||
| @@ -48,7 +46,7 @@ func (t *DownloadPackage) Execute(ctx *DownloadPackageContext) error { | |||||
| } | } | ||||
| var objIter iterator.DownloadingObjectIterator | var objIter iterator.DownloadingObjectIterator | ||||
| if getPkgResp.Redundancy.Type == models.RedundancyRep { | |||||
| if getPkgResp.Redundancy.IsRepInfo() { | |||||
| objIter, err = t.downloadRep(ctx) | objIter, err = t.downloadRep(ctx) | ||||
| } else { | } else { | ||||
| objIter, err = t.downloadEC(ctx, getPkgResp.Package) | objIter, err = t.downloadEC(ctx, getPkgResp.Package) | ||||
| @@ -102,21 +100,18 @@ func (t *DownloadPackage) downloadEC(ctx *DownloadPackageContext, pkg model.Pack | |||||
| return nil, fmt.Errorf("getting package object ec data: %w", err) | return nil, fmt.Errorf("getting package object ec data: %w", err) | ||||
| } | } | ||||
| var ecRed models.ECRedundancyInfo | |||||
| if err := serder.AnyToAny(pkg.Redundancy.Info, &ecRed); err != nil { | |||||
| var ecInfo models.ECRedundancyInfo | |||||
| if ecInfo, err = pkg.Redundancy.ToECInfo(); err != nil { | |||||
| return nil, fmt.Errorf("get ec redundancy info: %w", err) | return nil, fmt.Errorf("get ec redundancy info: %w", err) | ||||
| } | } | ||||
| getECResp, err := coorCli.GetECConfig(coormq.NewGetECConfig(ecRed.ECName)) | |||||
| getECResp, err := coorCli.GetECConfig(coormq.NewGetECConfig(ecInfo.ECName)) | |||||
| if err != nil { | if err != nil { | ||||
| return nil, fmt.Errorf("getting ec: %w", err) | return nil, fmt.Errorf("getting ec: %w", err) | ||||
| } | } | ||||
| iter := iterator.NewECObjectIterator(getObjsResp.Objects, getObjECDataResp.Data, getECResp.Config, &iterator.ECDownloadContext{ | |||||
| DownloadContext: &iterator.DownloadContext{ | |||||
| Distlock: ctx.Distlock, | |||||
| }, | |||||
| ECPacketSize: ctx.ECPacketSize, | |||||
| iter := iterator.NewECObjectIterator(getObjsResp.Objects, getObjECDataResp.Data, ecInfo, getECResp.Config, &iterator.DownloadContext{ | |||||
| Distlock: ctx.Distlock, | |||||
| }) | }) | ||||
| return iter, nil | return iter, nil | ||||
| @@ -5,7 +5,6 @@ import ( | |||||
| "github.com/samber/lo" | "github.com/samber/lo" | ||||
| "gitlink.org.cn/cloudream/common/models" | "gitlink.org.cn/cloudream/common/models" | ||||
| "gitlink.org.cn/cloudream/common/utils/serder" | |||||
| "gitlink.org.cn/cloudream/storage-common/globals" | "gitlink.org.cn/cloudream/storage-common/globals" | ||||
| "gitlink.org.cn/cloudream/storage-common/pkgs/db/model" | "gitlink.org.cn/cloudream/storage-common/pkgs/db/model" | ||||
| @@ -32,7 +31,7 @@ func NewUpdateECPackage(userID int64, packageID int64, objIter iterator.Uploadin | |||||
| } | } | ||||
| } | } | ||||
| func (t *UpdateECPackage) Execute(ctx *UpdateECPackageContext) (*UpdateECPackageResult, error) { | |||||
| func (t *UpdateECPackage) Execute(ctx *UpdatePackageContext) (*UpdateECPackageResult, error) { | |||||
| defer t.objectIter.Close() | defer t.objectIter.Close() | ||||
| coorCli, err := globals.CoordinatorMQPool.Acquire() | coorCli, err := globals.CoordinatorMQPool.Acquire() | ||||
| @@ -80,12 +79,12 @@ func (t *UpdateECPackage) Execute(ctx *UpdateECPackageContext) (*UpdateECPackage | |||||
| } | } | ||||
| }) | }) | ||||
| var ecRed models.ECRedundancyInfo | |||||
| if err := serder.AnyToAny(getPkgResp.Package.Redundancy.Info, &ecRed); err != nil { | |||||
| var ecInfo models.ECRedundancyInfo | |||||
| if ecInfo, err = getPkgResp.Package.Redundancy.ToECInfo(); err != nil { | |||||
| return nil, fmt.Errorf("get ec redundancy info: %w", err) | return nil, fmt.Errorf("get ec redundancy info: %w", err) | ||||
| } | } | ||||
| getECResp, err := coorCli.GetECConfig(coormq.NewGetECConfig(ecRed.ECName)) | |||||
| getECResp, err := coorCli.GetECConfig(coormq.NewGetECConfig(ecInfo.ECName)) | |||||
| if err != nil { | if err != nil { | ||||
| return nil, fmt.Errorf("getting ec: %w", err) | return nil, fmt.Errorf("getting ec: %w", err) | ||||
| } | } | ||||
| @@ -110,7 +109,7 @@ func (t *UpdateECPackage) Execute(ctx *UpdateECPackageContext) (*UpdateECPackage | |||||
| } | } | ||||
| defer ipfsMutex.Unlock() | defer ipfsMutex.Unlock() | ||||
| rets, err := uploadAndUpdateECPackage(ctx, t.packageID, t.objectIter, nodeInfos, getECResp.Config) | |||||
| rets, err := uploadAndUpdateECPackage(t.packageID, t.objectIter, nodeInfos, ecInfo, getECResp.Config) | |||||
| if err != nil { | if err != nil { | ||||
| return nil, err | return nil, err | ||||
| } | } | ||||
| @@ -128,7 +128,7 @@ func (db *PackageDB) SoftDelete(ctx SQLContext, packageID int64) error { | |||||
| return fmt.Errorf("change package state failed, err: %w", err) | return fmt.Errorf("change package state failed, err: %w", err) | ||||
| } | } | ||||
| if obj.Redundancy.Type == models.RedundancyRep { | |||||
| if obj.Redundancy.IsRepInfo() { | |||||
| err = db.ObjectRep().DeleteInPackage(ctx, packageID) | err = db.ObjectRep().DeleteInPackage(ctx, packageID) | ||||
| if err != nil { | if err != nil { | ||||
| return fmt.Errorf("delete from object rep failed, err: %w", err) | return fmt.Errorf("delete from object rep failed, err: %w", err) | ||||
| @@ -7,9 +7,10 @@ import ( | |||||
| "os" | "os" | ||||
| "github.com/samber/lo" | "github.com/samber/lo" | ||||
| "gitlink.org.cn/cloudream/common/models" | |||||
| "gitlink.org.cn/cloudream/common/pkgs/logger" | "gitlink.org.cn/cloudream/common/pkgs/logger" | ||||
| "gitlink.org.cn/cloudream/storage-common/globals" | "gitlink.org.cn/cloudream/storage-common/globals" | ||||
| "gitlink.org.cn/cloudream/storage-common/models" | |||||
| stgmodels "gitlink.org.cn/cloudream/storage-common/models" | |||||
| "gitlink.org.cn/cloudream/storage-common/pkgs/db/model" | "gitlink.org.cn/cloudream/storage-common/pkgs/db/model" | ||||
| "gitlink.org.cn/cloudream/storage-common/pkgs/ec" | "gitlink.org.cn/cloudream/storage-common/pkgs/ec" | ||||
| coormq "gitlink.org.cn/cloudream/storage-common/pkgs/mq/coordinator" | coormq "gitlink.org.cn/cloudream/storage-common/pkgs/mq/coordinator" | ||||
| @@ -19,24 +20,21 @@ type ECObjectIterator struct { | |||||
| OnClosing func() | OnClosing func() | ||||
| objects []model.Object | objects []model.Object | ||||
| objectECData []models.ObjectECData | |||||
| objectECData []stgmodels.ObjectECData | |||||
| currentIndex int | currentIndex int | ||||
| inited bool | inited bool | ||||
| ecInfo models.ECRedundancyInfo | |||||
| ec model.Ec | ec model.Ec | ||||
| downloadCtx *ECDownloadContext | |||||
| downloadCtx *DownloadContext | |||||
| cliLocation model.Location | cliLocation model.Location | ||||
| } | } | ||||
| type ECDownloadContext struct { | |||||
| *DownloadContext | |||||
| ECPacketSize int64 | |||||
| } | |||||
| func NewECObjectIterator(objects []model.Object, objectECData []models.ObjectECData, ec model.Ec, downloadCtx *ECDownloadContext) *ECObjectIterator { | |||||
| func NewECObjectIterator(objects []model.Object, objectECData []stgmodels.ObjectECData, ecInfo models.ECRedundancyInfo, ec model.Ec, downloadCtx *DownloadContext) *ECObjectIterator { | |||||
| return &ECObjectIterator{ | return &ECObjectIterator{ | ||||
| objects: objects, | objects: objects, | ||||
| objectECData: objectECData, | objectECData: objectECData, | ||||
| ecInfo: ecInfo, | |||||
| ec: ec, | ec: ec, | ||||
| downloadCtx: downloadCtx, | downloadCtx: downloadCtx, | ||||
| } | } | ||||
| @@ -146,7 +144,7 @@ func (i *ECObjectIterator) chooseDownloadNode(entries []DownloadNodeInfo) Downlo | |||||
| func (iter *ECObjectIterator) downloadEcObject(fileSize int64, ecK int, ecN int, blockIDs []int, nodeIDs []int64, nodeIPs []string, hashs []string) (io.ReadCloser, error) { | func (iter *ECObjectIterator) downloadEcObject(fileSize int64, ecK int, ecN int, blockIDs []int, nodeIDs []int64, nodeIPs []string, hashs []string) (io.ReadCloser, error) { | ||||
| // TODO zkx 先试用同步方式实现逻辑,做好错误处理。同时也方便下面直接使用uploadToNode和uploadToLocalIPFS来优化代码结构 | // TODO zkx 先试用同步方式实现逻辑,做好错误处理。同时也方便下面直接使用uploadToNode和uploadToLocalIPFS来优化代码结构 | ||||
| //wg := sync.WaitGroup{} | //wg := sync.WaitGroup{} | ||||
| numPacket := (fileSize + int64(ecK)*iter.downloadCtx.ECPacketSize - 1) / (int64(ecK) * iter.downloadCtx.ECPacketSize) | |||||
| numPacket := (fileSize + int64(ecK)*iter.ecInfo.PacketSize - 1) / (int64(ecK) * iter.ecInfo.PacketSize) | |||||
| getBufs := make([]chan []byte, ecN) | getBufs := make([]chan []byte, ecN) | ||||
| decodeBufs := make([]chan []byte, ecK) | decodeBufs := make([]chan []byte, ecK) | ||||
| for i := 0; i < ecN; i++ { | for i := 0; i < ecN; i++ { | ||||
| @@ -159,10 +157,10 @@ func (iter *ECObjectIterator) downloadEcObject(fileSize int64, ecK int, ecN int, | |||||
| i := idx | i := idx | ||||
| go func() { | go func() { | ||||
| // TODO 处理错误 | // TODO 处理错误 | ||||
| file, _ := downloadFile(iter.downloadCtx.DownloadContext, nodeIDs[i], nodeIPs[i], hashs[i]) | |||||
| file, _ := downloadFile(iter.downloadCtx, nodeIDs[i], nodeIPs[i], hashs[i]) | |||||
| for p := int64(0); p < numPacket; p++ { | for p := int64(0); p < numPacket; p++ { | ||||
| buf := make([]byte, iter.downloadCtx.ECPacketSize) | |||||
| buf := make([]byte, iter.ecInfo.PacketSize) | |||||
| // TODO 处理错误 | // TODO 处理错误 | ||||
| io.ReadFull(file, buf) | io.ReadFull(file, buf) | ||||
| getBufs[blockIDs[i]] <- buf | getBufs[blockIDs[i]] <- buf | ||||