package fs import ( "fmt" "io" gofs "io/fs" "time" "github.com/datarhei/core/v16/cluster/node" "github.com/datarhei/core/v16/io/fs" ) type Filesystem interface { fs.Filesystem } type filesystem struct { fs.Filesystem name string proxy *node.Manager } func NewClusterFS(name string, fs fs.Filesystem, proxy *node.Manager) Filesystem { if proxy == nil { return fs } f := &filesystem{ Filesystem: fs, name: name, proxy: proxy, } return f } func (cfs *filesystem) Open(path string) fs.File { // Check if the file is locally available //if file := fs.Filesystem.Open(path); file != nil { // return file //} // Check if the file is available in the cluster size, lastModified, err := cfs.proxy.FilesystemGetFileInfo(cfs.name, path) if err != nil { return nil } file := &file{ getFile: func(offset int64) (io.ReadCloser, error) { return cfs.proxy.FilesystemGetFile(cfs.name, path, offset) }, name: path, size: size, lastModified: lastModified, } return file } type file struct { io.ReadCloser getFile func(offset int64) (io.ReadCloser, error) name string size int64 lastModified time.Time } func (f *file) Read(p []byte) (int, error) { if f.ReadCloser == nil { data, err := f.getFile(0) if err != nil { return 0, err } f.ReadCloser = data } return f.ReadCloser.Read(p) } func (f *file) Close() error { if f.ReadCloser == nil { return nil } return f.ReadCloser.Close() } func (f *file) Seek(offset int64, whence int) (int64, error) { if whence != io.SeekStart { return 0, fmt.Errorf("not implemented") } if f.ReadCloser != nil { f.ReadCloser.Close() f.ReadCloser = nil } if f.ReadCloser == nil { data, err := f.getFile(offset) if err != nil { return 0, err } f.ReadCloser = data } return offset, nil } func (f *file) Name() string { return f.name } func (f *file) Stat() (fs.FileInfo, error) { return f, nil } func (f *file) Mode() gofs.FileMode { return gofs.FileMode(gofs.ModePerm) } func (f *file) Size() int64 { return f.size } func (f *file) ModTime() time.Time { return f.lastModified } func (f *file) IsLink() (string, bool) { return "", false } func (f *file) IsDir() bool { return false }