1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: Apache-2.0
14 func deferredCollectionFS(fs FileSystem, parent inode, coll Collection) inode {
15 modTime := coll.ModifiedAt
19 placeholder := &treenode{
26 mode: 0755 | os.ModeDir,
29 return &deferrednode{wrapped: placeholder, create: func() inode {
30 err := fs.RequestAndDecode(&coll, "GET", "arvados/v1/collections/"+coll.UUID, nil, nil)
32 log.Printf("BUG: unhandled error: %s", err)
35 cfs, err := coll.FileSystem(fs, fs)
37 log.Printf("BUG: unhandled error: %s", err)
40 root := cfs.rootnode()
41 root.SetParent(parent, coll.Name)
46 // A deferrednode wraps an inode that's expensive to build. Initially,
47 // it responds to basic directory functions by proxying to the given
48 // placeholder. If a caller uses a read/write/lock operation,
49 // deferrednode calls the create() func to create the real inode, and
50 // proxies to the real inode from then on.
52 // In practice, this means a deferrednode's parent's directory listing
53 // can be generated using only the placeholder, instead of waiting for
55 type deferrednode struct {
62 func (dn *deferrednode) realinode() inode {
66 dn.wrapped = dn.create()
72 func (dn *deferrednode) currentinode() inode {
78 func (dn *deferrednode) Read(p []byte, pos filenodePtr) (int, filenodePtr, error) {
79 return dn.realinode().Read(p, pos)
82 func (dn *deferrednode) Write(p []byte, pos filenodePtr) (int, filenodePtr, error) {
83 return dn.realinode().Write(p, pos)
86 func (dn *deferrednode) Child(name string, replace func(inode) (inode, error)) (inode, error) {
87 return dn.realinode().Child(name, replace)
90 func (dn *deferrednode) Truncate(size int64) error { return dn.realinode().Truncate(size) }
91 func (dn *deferrednode) SetParent(p inode, name string) { dn.realinode().SetParent(p, name) }
92 func (dn *deferrednode) IsDir() bool { return dn.currentinode().IsDir() }
93 func (dn *deferrednode) Readdir() ([]os.FileInfo, error) { return dn.realinode().Readdir() }
94 func (dn *deferrednode) Size() int64 { return dn.currentinode().Size() }
95 func (dn *deferrednode) FileInfo() os.FileInfo { return dn.currentinode().FileInfo() }
96 func (dn *deferrednode) Lock() { dn.realinode().Lock() }
97 func (dn *deferrednode) Unlock() { dn.realinode().Unlock() }
98 func (dn *deferrednode) RLock() { dn.realinode().RLock() }
99 func (dn *deferrednode) RUnlock() { dn.realinode().RUnlock() }
100 func (dn *deferrednode) FS() FileSystem { return dn.currentinode().FS() }
101 func (dn *deferrednode) Parent() inode { return dn.currentinode().Parent() }