19362: Sync s3 updates to long-lived session for same token.
[arvados.git] / sdk / go / arvados / fs_project.go
index 4db87a591eebabad096bb988204f6c90e9ad7ef0..a68e83945e348a0f3e740b7c0a313155917b795a 100644 (file)
@@ -6,7 +6,9 @@ package arvados
 
 import (
        "log"
+       "os"
        "strings"
+       "time"
 )
 
 func (fs *customFileSystem) defaultUUID(uuid string) (string, error) {
@@ -64,9 +66,18 @@ func (fs *customFileSystem) projectsLoadOne(parent inode, uuid, name string) (in
        if strings.Contains(coll.UUID, "-j7d0g-") {
                // Group item was loaded into a Collection var -- but
                // we only need the Name and UUID anyway, so it's OK.
-               return fs.newProjectNode(parent, coll.Name, coll.UUID, coll.Properties), nil
+               return &hardlink{
+                       inode: fs.projectSingleton(coll.UUID, &Group{
+                               UUID:       coll.UUID,
+                               Name:       coll.Name,
+                               ModifiedAt: coll.ModifiedAt,
+                               Properties: coll.Properties,
+                       }),
+                       parent: parent,
+                       name:   coll.Name,
+               }, nil
        } else if strings.Contains(coll.UUID, "-4zz18-") {
-               return deferredCollectionFS(fs, parent, coll), nil
+               return fs.newDeferredCollectionDir(parent, name, coll.UUID, coll.ModifiedAt, coll.Properties), nil
        } else {
                log.Printf("group contents: unrecognized UUID in response: %q", coll.UUID)
                return nil, ErrInvalidArgument
@@ -79,6 +90,7 @@ func (fs *customFileSystem) projectsLoadAll(parent inode, uuid string) ([]inode,
                return nil, err
        }
 
+       pagesize := 100000
        var inodes []inode
 
        // When #17424 is resolved, remove the outer loop here and use
@@ -100,13 +112,18 @@ func (fs *customFileSystem) projectsLoadAll(parent inode, uuid string) ([]inode,
                        Filters: filters,
                        Order:   "uuid",
                        Select:  []string{"uuid", "name", "modified_at", "properties"},
+                       Limit:   &pagesize,
                }
 
                for {
-                       // The groups content endpoint returns Collection and Group (project)
-                       // objects. This function only accesses the UUID and Name field. Both
-                       // collections and groups have those fields, so it is easier to just treat
-                       // the ObjectList that comes back as a CollectionList.
+                       // The groups content endpoint returns
+                       // Collection and Group (project)
+                       // objects. This function only accesses the
+                       // UUID, Name, and ModifiedAt fields. Both
+                       // collections and groups have those fields,
+                       // so it is easier to just treat the
+                       // ObjectList that comes back as a
+                       // CollectionList.
                        var resp CollectionList
                        err = fs.RequestAndDecode(&resp, "GET", "arvados/v1/groups/"+uuid+"/contents", nil, params)
                        if err != nil {
@@ -123,9 +140,14 @@ func (fs *customFileSystem) projectsLoadAll(parent inode, uuid string) ([]inode,
                                        continue
                                }
                                if strings.Contains(i.UUID, "-j7d0g-") {
-                                       inodes = append(inodes, fs.newProjectNode(parent, i.Name, i.UUID, i.Properties))
+                                       inodes = append(inodes, fs.newProjectDir(parent, i.Name, i.UUID, &Group{
+                                               UUID:       i.UUID,
+                                               Name:       i.Name,
+                                               ModifiedAt: i.ModifiedAt,
+                                               Properties: i.Properties,
+                                       }))
                                } else if strings.Contains(i.UUID, "-4zz18-") {
-                                       inodes = append(inodes, deferredCollectionFS(fs, parent, i))
+                                       inodes = append(inodes, fs.newDeferredCollectionDir(parent, i.Name, i.UUID, i.ModifiedAt, i.Properties))
                                } else {
                                        log.Printf("group contents: unrecognized UUID in response: %q", i.UUID)
                                        return nil, ErrInvalidArgument
@@ -136,3 +158,32 @@ func (fs *customFileSystem) projectsLoadAll(parent inode, uuid string) ([]inode,
        }
        return inodes, nil
 }
+
+func (fs *customFileSystem) newProjectDir(parent inode, name, uuid string, proj *Group) inode {
+       return &hardlink{inode: fs.projectSingleton(uuid, proj), parent: parent, name: name}
+}
+
+func (fs *customFileSystem) newDeferredCollectionDir(parent inode, name, uuid string, modTime time.Time, props map[string]interface{}) inode {
+       if modTime.IsZero() {
+               modTime = time.Now()
+       }
+       placeholder := &treenode{
+               fs:     fs,
+               parent: parent,
+               inodes: nil,
+               fileinfo: fileinfo{
+                       name:    name,
+                       modTime: modTime,
+                       mode:    0755 | os.ModeDir,
+                       sys:     func() interface{} { return &Collection{UUID: uuid, Name: name, ModifiedAt: modTime, Properties: props} },
+               },
+       }
+       return &deferrednode{wrapped: placeholder, create: func() inode {
+               node, err := fs.collectionSingleton(uuid)
+               if err != nil {
+                       log.Printf("BUG: unhandled error: %s", err)
+                       return placeholder
+               }
+               return &hardlink{inode: node, parent: parent, name: name}
+       }}
+}