diff --git a/go.mod b/go.mod index 53a606f175..5860e7239b 100644 --- a/go.mod +++ b/go.mod @@ -79,6 +79,7 @@ require ( github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver v1.5.0 // indirect + github.com/alitto/pond v1.8.3 github.com/armon/go-metrics v0.4.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/beorn7/perks v1.0.1 // indirect diff --git a/go.sum b/go.sum index 6c53517a6c..83c7cc80c5 100644 --- a/go.sum +++ b/go.sum @@ -835,6 +835,8 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5 github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= +github.com/alitto/pond v1.8.3 h1:ydIqygCLVPqIX/USe5EaV/aSRXTRXDEI9JwuDdu+/xs= +github.com/alitto/pond v1.8.3/go.mod h1:CmvIIGd5jKLasGI3D87qDkQxjzChdKMmnXMg3fG6M6Q= github.com/aliyun/alibaba-cloud-sdk-go v1.61.976/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA= github.com/andrewmostello/go-tus v0.0.0-20200314041820-904a9904af9a h1:6tD4saJb8wmYF6Llz96ZJwUQ5r2GyTBFA2VEB5z8gVY= github.com/andrewmostello/go-tus v0.0.0-20200314041820-904a9904af9a/go.mod h1:XYuK1S5+kS6FGhlIUFuZFPvWiSrOIoLk6+ro33Xce3Y= diff --git a/internal/http/services/owncloud/ocgraph/drives.go b/internal/http/services/owncloud/ocgraph/drives.go index 3af162c12d..61e4eb02d6 100644 --- a/internal/http/services/owncloud/ocgraph/drives.go +++ b/internal/http/services/owncloud/ocgraph/drives.go @@ -32,6 +32,7 @@ import ( "time" "github.com/CiscoM31/godata" + "github.com/alitto/pond" gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" @@ -130,55 +131,75 @@ func getDrivesForShares(ctx context.Context, gw gateway.GatewayAPIClient) ([]*li return nil, errors.New(res.Status.Message) } + pool := pond.New(50, len(res.Shares)) + spaces := make(chan *libregraph.Drive, len(res.Shares)) + spacesRes := make([]*libregraph.Drive, 0, len(res.Shares)) for _, s := range res.Shares { - if s.State == collaborationv1beta1.ShareState_SHARE_STATE_REJECTED || s.State == collaborationv1beta1.ShareState_SHARE_STATE_INVALID { - continue - } - share := s.Share - stat, err := gw.Stat(ctx, &providerpb.StatRequest{ - Ref: &providerpb.Reference{ - ResourceId: share.ResourceId, - }, - }) - if err != nil { - return nil, err - } + s := s + pool.Submit(func() { + if s.State == collaborationv1beta1.ShareState_SHARE_STATE_REJECTED || s.State == collaborationv1beta1.ShareState_SHARE_STATE_INVALID { + return + } + share := s.Share + stat, err := gw.Stat(ctx, &providerpb.StatRequest{ + Ref: &providerpb.Reference{ + ResourceId: share.ResourceId, + }, + }) + if err != nil { + return + } - if stat.Status.Code != rpcv1beta1.Code_CODE_OK { - continue - } + if stat.Status.Code != rpcv1beta1.Code_CODE_OK { + return + } - // the prefix of the remote_item.id and rootid - idPrefix := base64.StdEncoding.EncodeToString([]byte(stat.Info.Path)) - resourceIdEnc := base64.StdEncoding.EncodeToString([]byte(resourceid.OwnCloudResourceIDWrap(stat.Info.Id))) + // the prefix of the remote_item.id and rootid + idPrefix := base64.StdEncoding.EncodeToString([]byte(stat.Info.Path)) + resourceIdEnc := base64.StdEncoding.EncodeToString([]byte(resourceid.OwnCloudResourceIDWrap(stat.Info.Id))) - space := &libregraph.Drive{ - Id: libregraph.PtrString(fmt.Sprintf("%s$%s!%s", shareJailID, shareJailID, share.Id.OpaqueId)), - DriveType: libregraph.PtrString("mountpoint"), - DriveAlias: libregraph.PtrString(share.Id.OpaqueId), // this is not used, but must not be the same alias as the drive item - Name: filepath.Base(stat.Info.Path), - Root: &libregraph.DriveItem{ - Id: libregraph.PtrString(fmt.Sprintf("%s$%s!%s", shareJailID, shareJailID, share.Id.OpaqueId)), - RemoteItem: &libregraph.RemoteItem{ - DriveAlias: libregraph.PtrString(strings.TrimPrefix(stat.Info.Path, "/")), // the drive alias must not start with / - ETag: libregraph.PtrString(stat.Info.Etag), - Folder: &libregraph.Folder{}, - // The Id must correspond to the id in the OCS response, for the time being - // It is in the form ! - Id: libregraph.PtrString(fmt.Sprintf("%s!%s", idPrefix, resourceIdEnc)), - LastModifiedDateTime: libregraph.PtrTime(time.Unix(int64(stat.Info.Mtime.Seconds), int64(stat.Info.Mtime.Nanos))), - Name: libregraph.PtrString(filepath.Base(stat.Info.Path)), - Path: libregraph.PtrString("/"), - // RootId must have the same token before ! as Id - // the second part for the time being is not important - RootId: libregraph.PtrString(fmt.Sprintf("%s!wrong_root_id", idPrefix)), - Size: libregraph.PtrInt64(int64(stat.Info.Size)), + space := &libregraph.Drive{ + Id: libregraph.PtrString(fmt.Sprintf("%s$%s!%s", shareJailID, shareJailID, share.Id.OpaqueId)), + DriveType: libregraph.PtrString("mountpoint"), + DriveAlias: libregraph.PtrString(share.Id.OpaqueId), // this is not used, but must not be the same alias as the drive item + Name: filepath.Base(stat.Info.Path), + Root: &libregraph.DriveItem{ + Id: libregraph.PtrString(fmt.Sprintf("%s$%s!%s", shareJailID, shareJailID, share.Id.OpaqueId)), + RemoteItem: &libregraph.RemoteItem{ + DriveAlias: libregraph.PtrString(strings.TrimPrefix(stat.Info.Path, "/")), // the drive alias must not start with / + ETag: libregraph.PtrString(stat.Info.Etag), + Folder: &libregraph.Folder{}, + // The Id must correspond to the id in the OCS response, for the time being + // It is in the form ! + Id: libregraph.PtrString(fmt.Sprintf("%s!%s", idPrefix, resourceIdEnc)), + LastModifiedDateTime: libregraph.PtrTime(time.Unix(int64(stat.Info.Mtime.Seconds), int64(stat.Info.Mtime.Nanos))), + Name: libregraph.PtrString(filepath.Base(stat.Info.Path)), + Path: libregraph.PtrString("/"), + // RootId must have the same token before ! as Id + // the second part for the time being is not important + RootId: libregraph.PtrString(fmt.Sprintf("%s!wrong_root_id", idPrefix)), + Size: libregraph.PtrInt64(int64(stat.Info.Size)), + }, }, - }, - } - spacesRes = append(spacesRes, space) + } + spaces <- space + }) } + + done := make(chan struct{}) + go func() { + for s := range spaces { + spacesRes = append(spacesRes, s) + } + done <- struct{}{} + }() + + pool.StopAndWait() + close(spaces) + <-done + close(done) + return spacesRes, nil }