19368: Use Sys() instead of .arvados# file to get collection ID. 19368-webdav-logging-speedup
authorTom Clegg <tom@curii.com>
Thu, 11 Aug 2022 14:36:00 +0000 (10:36 -0400)
committerTom Clegg <tom@curii.com>
Thu, 11 Aug 2022 14:36:00 +0000 (10:36 -0400)
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom@curii.com>

sdk/go/arvados/fs_collection.go
services/keep-web/handler.go

index eb3e974ede506aa33997addb72859d78839eb006..26012e240603d0be43a1019346c4e946e2821790 100644 (file)
@@ -954,17 +954,6 @@ func (dn *dirnode) Child(name string, replace func(inode) (inode, error)) (inode
                gn.SetParent(dn, name)
                return gn, nil
        }
-       if dn == dn.fs.rootnode() && name == ".arvados#collection_id" {
-               gn := &getternode{Getter: func() ([]byte, error) {
-                       data, err := json.Marshal(Collection{UUID: dn.fs.uuid})
-                       if err == nil {
-                               data = append(data, '\n')
-                       }
-                       return data, err
-               }}
-               gn.SetParent(dn, name)
-               return gn, nil
-       }
        return dn.treenode.Child(name, replace)
 }
 
index a6187043bdb60eb45a40cb8d602a3aee98c17fe0..3a1d9acde7e7d33208958e467931aef2b1474853 100644 (file)
@@ -909,17 +909,18 @@ func (h *handler) logUploadOrDownload(
                collection, filepath = h.determineCollection(fs, filepath)
        }
        if collection != nil {
-               log = log.WithField("collection_uuid", collection.UUID).
-                       WithField("collection_file_path", filepath)
-               props["collection_uuid"] = collection.UUID
+               log = log.WithField("collection_file_path", filepath)
                props["collection_file_path"] = filepath
-               // h.determineCollection populates the collection_uuid prop with the PDH, if
-               // this collection is being accessed via PDH. In that case, blank the
-               // collection_uuid field so that consumers of the log entries can rely on it
-               // being a UUID, or blank. The PDH remains available via the
-               // portable_data_hash property.
-               if props["collection_uuid"] == collection.PortableDataHash {
-                       props["collection_uuid"] = ""
+               // h.determineCollection populates the collection_uuid
+               // prop with the PDH, if this collection is being
+               // accessed via PDH. For logging, we use a different
+               // field depending on whether it's a UUID or PDH.
+               if len(collection.UUID) > 32 {
+                       log = log.WithField("portable_data_hash", collection.UUID)
+                       props["portable_data_hash"] = collection.UUID
+               } else {
+                       log = log.WithField("collection_uuid", collection.UUID)
+                       props["collection_uuid"] = collection.UUID
                }
        }
        if r.Method == "PUT" || r.Method == "POST" {
@@ -958,29 +959,27 @@ func (h *handler) logUploadOrDownload(
 }
 
 func (h *handler) determineCollection(fs arvados.CustomFileSystem, path string) (*arvados.Collection, string) {
-       segments := strings.Split(path, "/")
-       var i int
-       for i = 0; i < len(segments); i++ {
-               dir := append([]string{}, segments[0:i]...)
-               dir = append(dir, ".arvados#collection_id")
-               f, err := fs.OpenFile(strings.Join(dir, "/"), os.O_RDONLY, 0)
-               if f != nil {
-                       defer f.Close()
-               }
+       target := strings.TrimSuffix(path, "/")
+       for {
+               fi, err := fs.Stat(target)
                if err != nil {
-                       if !os.IsNotExist(err) {
+                       return nil, ""
+               }
+               switch src := fi.Sys().(type) {
+               case *arvados.Collection:
+                       return src, strings.TrimPrefix(path[len(target):], "/")
+               case *arvados.Group:
+                       return nil, ""
+               default:
+                       if _, ok := src.(error); ok {
                                return nil, ""
                        }
-                       continue
                }
-               // err is nil so we found it.
-               decoder := json.NewDecoder(f)
-               var collection arvados.Collection
-               err = decoder.Decode(&collection)
-               if err != nil {
+               // Try parent
+               cut := strings.LastIndexByte(target, '/')
+               if cut < 0 {
                        return nil, ""
                }
-               return &collection, strings.Join(segments[i:], "/")
+               target = target[:cut]
        }
-       return nil, ""
 }