From 4fa2a5b02cf29bc246ecd2049ecf64e97fe9a51d Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Tue, 6 Oct 2026 11:17:45 +0100 Subject: [PATCH] vfs: add Busy to tell if a VFS still has data to write Busy returns true if the VFS has files open for write or files in the VFS cache which are open or waiting to be uploaded. It is for code which wants to shut a VFS down only once that wouldn't lose any work. --- vfs/vfs.go | 25 ++++++++++++++++++++----- vfs/vfs_test.go | 22 ++++++++++++++++++++++ 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/vfs/vfs.go b/vfs/vfs.go index 1d6ac1631..bb1951484 100644 --- a/vfs/vfs.go +++ b/vfs/vfs.go @@ -457,6 +457,25 @@ func (vfs *VFS) FlushDirCache() { vfs.root.ForgetAll() } +// countInUse returns the number of files open for write and the +// number of cached files which are open or waiting to be uploaded. +func (vfs *VFS) countInUse() (writers, cacheInUse int) { + writers = vfs.root.countActiveWriters() + if vfs.cache != nil { + cacheInUse = vfs.cache.TotalInUse() + } + return writers, cacheInUse +} + +// Busy returns true if the VFS has files open for write or cached +// files which are open or waiting to be uploaded. +// +// It may block while a directory is being read from the remote. +func (vfs *VFS) Busy() bool { + writers, cacheInUse := vfs.countInUse() + return writers != 0 || cacheInUse != 0 +} + // WaitForWriters sleeps until all writers have finished or // time.Duration has elapsed func (vfs *VFS) WaitForWriters(timeout time.Duration) { @@ -468,11 +487,7 @@ func (vfs *VFS) WaitForWriters(timeout time.Duration) { defer tick.Stop() tick.Stop() for { - writers := vfs.root.countActiveWriters() - cacheInUse := 0 - if vfs.cache != nil { - cacheInUse = vfs.cache.TotalInUse() - } + writers, cacheInUse := vfs.countInUse() if writers == 0 && cacheInUse == 0 { return } diff --git a/vfs/vfs_test.go b/vfs/vfs_test.go index 710674a80..67a143423 100644 --- a/vfs/vfs_test.go +++ b/vfs/vfs_test.go @@ -190,6 +190,28 @@ func TestVFSNewShuttingDown(t *testing.T) { vfs2.Shutdown() } +// TestVFSBusy checks Busy reports files open for write and cached +// files which haven't been uploaded yet. +func TestVFSBusy(t *testing.T) { + opt := vfscommon.Opt + opt.CacheMode = vfscommon.CacheModeWrites + opt.WriteBack = 10 * writeBackDelay + _, vfs := newTestVFSOpt(t, &opt) + assert.False(t, vfs.Busy()) + + fh, err := vfs.Create("file.txt") + require.NoError(t, err) + assert.True(t, vfs.Busy(), "not busy with a file open for write") + + _, err = fh.WriteString("hello") + require.NoError(t, err) + require.NoError(t, fh.Close()) + assert.True(t, vfs.Busy(), "not busy with a file waiting to be uploaded") + + vfs.WaitForWriters(waitForWritersDelay) + assert.False(t, vfs.Busy(), "busy after the file was uploaded") +} + // TestVFSNewWithOpts sees if the New command works properly func TestVFSNewWithOpts(t *testing.T) { var opt = vfscommon.Opt