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