Folder Watcher - SilverEzhik/fmtest GitHub Wiki

The folder watcher is implemented using fsnotify.

Internally, a folder has the following structure:

type folder struct {
	path     string
	contents map[string]os.FileInfo
	m        sync.Mutex
	watchers []chan bool
	done     chan struct{}
	uid      uint64
	count    uint64
}

type mutexFolders struct {
	f map[string]*folder
	m sync.Mutex
}

GetFolder(path)

GetFolder(path) returns a fm.Folder object.

The GetFolder(path) implementation first checks if the path is already being watched (by checking the mutexFolders map), and returns a pointer to that, otherwise, it creates a new folder object and returns it.

Contents()

Contents() returns a copy of a folder struct's contents.

If a folder is being watched, then it just returns the current contents. If it is not being watched, it performs a Refresh() first.

Watch()

Watch() returns a channel that is pinged when a folder is updated.

If there is no active folder watcher (that is, if the count value in the struct is 0), it also automatically starts the folder's watcher.

Close()

Close() is used to dispose of a folder object once it is no longer used.

If the folder was watched more than once, then the count value is simply decremented by one. If the last subscriber is done with the folder, then the watcher is closed and the folder is disposed of. interface considerations: should running Close() on a folder object just close the watcher, or dispose of the folder?


The following methods are not a part of the Folder interface, but are used internally in the FS implementation:

Refresh()

fsWatcher()

This is the goroutine where all the interaction with fsnotify happens.

notifyWatchers() and closeWatchers()

cleanup()

The function called when the folder goes missing.

updateItem() and removeItem()