pub struct WATCHER;Expand description
File system watcher service.
This is mostly a wrapper around the notify crate, integrating it with events and variables.
§Provider
This service is provided by the FsWatcherManager extension, it will panic if used in an app not extended.
Implementations§
Source§impl WATCHER
impl WATCHER
Sourcepub fn debounce(&self) -> Var<Duration>
pub fn debounce(&self) -> Var<Duration>
Gets a read-write variable that defines interval awaited between each FS_CHANGES_EVENT. If
a watched path is constantly changing an event will be emitted every elapse of this interval,
the event args will contain a list of all the changes observed during the interval.
Note that the first event notifies immediately, only subsequent events within this interval are debounced.
Is 100.ms() by default.
Sourcepub fn sync_debounce(&self) -> Var<Duration>
pub fn sync_debounce(&self) -> Var<Duration>
Gets a read-write variable that defines interval awaited between each sync write.
Is 100.ms() by default.
Sourcepub fn poll_interval(&self) -> Var<Duration>
pub fn poll_interval(&self) -> Var<Duration>
Gets a read-write variable that defines the fallback poll watcher interval.
When an efficient watcher cannot be used a poll watcher fallback is used, the poll watcher reads the directory or path every elapse of this interval. The poll watcher is also used for paths that do not exist yet, that is also affected by this interval.
Is 1.secs() by default.
Sourcepub fn shutdown_timeout(&self) -> Var<Duration>
pub fn shutdown_timeout(&self) -> Var<Duration>
Maximum time the service keeps the process alive to finish pending IO operations when the app shuts down.
Is 1 minute by default.
Sourcepub fn watch(&self, file: impl Into<PathBuf>) -> WatcherHandle
pub fn watch(&self, file: impl Into<PathBuf>) -> WatcherHandle
Enable file change events for the file.
Returns a handle that will stop the file watch when dropped, if there is no other active handler for the same file.
Note that this is implemented by actually watching the parent directory and filtering the events, this is done to ensure the watcher survives operations that remove the file and then move another file to the same path.
See watch_dir for more details.
Sourcepub fn watch_dir(
&self,
dir: impl Into<PathBuf>,
recursive: bool,
) -> WatcherHandle
pub fn watch_dir( &self, dir: impl Into<PathBuf>, recursive: bool, ) -> WatcherHandle
Enable file change events for files inside dir, also include inner directories if recursive is true.
Returns a handle that will stop the dir watch when dropped, if there is no other active handler for the same directory.
The directory will be watched using an OS specific efficient watcher provided by the notify crate. If there is
any error creating the watcher, such as if the directory does not exist yet a slower polling watcher will retry periodically
until the efficient watcher can be created or the handle is dropped.
Sourcepub fn read<O: VarValue>(
&self,
file: impl Into<PathBuf>,
init: O,
read: impl FnMut(Result<WatchFile>) -> Option<O> + Send + 'static,
) -> Var<O>
pub fn read<O: VarValue>( &self, file: impl Into<PathBuf>, init: O, read: impl FnMut(Result<WatchFile>) -> Option<O> + Send + 'static, ) -> Var<O>
Read a file into a variable, the init value will start the variable and the read closure will be called
once immediately and every time the file changes, if the closure returns Some(O) the variable updates with the new value.
Dropping the variable drops the read watch. The read closure is non-blocking, it is called in a task::wait
background thread.
Sourcepub fn read_status<O, S, E>(
&self,
file: impl Into<PathBuf>,
init: O,
read: impl FnMut(Result<WatchFile>) -> Result<Option<O>, E> + Send + 'static,
) -> (Var<O>, Var<S>)where
O: VarValue,
S: WatcherReadStatus<E>,
pub fn read_status<O, S, E>(
&self,
file: impl Into<PathBuf>,
init: O,
read: impl FnMut(Result<WatchFile>) -> Result<Option<O>, E> + Send + 'static,
) -> (Var<O>, Var<S>)where
O: VarValue,
S: WatcherReadStatus<E>,
Same operation as read but also tracks the operation status in a second var.
The status variable is set to WatcherReadStatus::reading as soon as read starts and
is set to WatcherReadStatus::idle when read returns. If read returns a value the status
only updates to idle when the new value is available on the var, or because read the same value.
Sourcepub fn read_dir<O: VarValue>(
&self,
dir: impl Into<PathBuf>,
recursive: bool,
init: O,
read: impl FnMut(WalkDir) -> Option<O> + Send + 'static,
) -> Var<O>
pub fn read_dir<O: VarValue>( &self, dir: impl Into<PathBuf>, recursive: bool, init: O, read: impl FnMut(WalkDir) -> Option<O> + Send + 'static, ) -> Var<O>
Read a directory into a variable, the init value will start the variable and the read closure will be called
once immediately and every time any changes happen inside the dir, if the closure returns Some(O) the variable updates with the new value.
The read closure parameter is a directory walker from the walkdir crate.
The directory walker is pre-configured to skip the dir itself and to have a max-depth of 1 if not recursive, these configs can.
Dropping the variable drops the read watch. The read closure is non-blocking, it is called in a task::wait
background thread.
Sourcepub fn read_dir_status<O, S, E>(
&self,
dir: impl Into<PathBuf>,
recursive: bool,
init: O,
read: impl FnMut(WalkDir) -> Result<Option<O>, E> + Send + 'static,
) -> (Var<O>, Var<S>)where
O: VarValue,
S: WatcherReadStatus<E>,
pub fn read_dir_status<O, S, E>(
&self,
dir: impl Into<PathBuf>,
recursive: bool,
init: O,
read: impl FnMut(WalkDir) -> Result<Option<O>, E> + Send + 'static,
) -> (Var<O>, Var<S>)where
O: VarValue,
S: WatcherReadStatus<E>,
Same operation as read_dir but also tracks the operation status in a second var.
The status variable is set to WatcherReadStatus::reading as soon as read starts and
is set to WatcherReadStatus::idle when read returns. If read returns a value the status
only updates to idle when the new value is available on the var, or because read the same value.
Sourcepub fn sync<O: VarValue>(
&self,
file: impl Into<PathBuf>,
init: O,
read: impl FnMut(Result<WatchFile>) -> Option<O> + Send + 'static,
write: impl FnMut(O, Result<WriteFile>) + Send + 'static,
) -> Var<O>
pub fn sync<O: VarValue>( &self, file: impl Into<PathBuf>, init: O, read: impl FnMut(Result<WatchFile>) -> Option<O> + Send + 'static, write: impl FnMut(O, Result<WriteFile>) + Send + 'static, ) -> Var<O>
Bind a file with a variable, the file will be read when it changes and be write when the variable changes,
writes are only applied on success and will not cause a read on the same sync task. The init value is used to
create the variable, if the file exists it will be read once at the beginning.
Dropping the variable drops the read watch. The read and write closures are non-blocking, they are called in a task::wait
background thread.
§Sync
The file synchronization ensures that the file is only actually modified when write is finished by writing
to a temporary file and committing a replace only if the write succeeded. The file is write-locked for the duration
of write call, but the contents are not touched until commit. See WriteFile for more details.
The FsWatcherManager blocks on app exit until all writes commit or cancel. See WATCHER::shutdown_timeout for
more details.
§Read Errors
Not-found errors are handled by the watcher by calling write using the current variable value, other read errors
are passed to read. If read returns a value for an error the write closure is called to override the file,
otherwise only the variable is set and this variable update does not cause a write.
§Write Errors
If write fails the file is not touched and the temporary file is removed, if the file path
does not exit all missing parent folders and the file will be created automatically before the write
call.
Note that WriteFile::commit must be called to flush the temporary file and attempt to rename
it, if the file is dropped without commit it will cancel and log an error, you must call WriteFile::cancel
to correctly avoid writing.
If the cleanup after commit fails the error is logged and ignored.
If write fails to even create the file and/or acquire a write lock on it this error is the input for
the write closure.
§Error Handling
You can call services or set other variables from inside the read and write closures, this can be
used to get a signal out to handle the error, perhaps drop the sync var (to stop watching), alert the user that the
file is out of sync and initiate some sort of recovery routine.
If the file synchronization is not important you can just ignore it, the watcher will try again on the next variable or file update.
§Status
Note that read and write run in background task threads, so if you are tracking the operation
status in a separate variable you may end-up with synchronization bugs between the status variable
and the actual result variable, you can use sync_status to implement racing-free status tracking.
Sourcepub fn sync_status<O, S, ER, EW>(
&self,
file: impl Into<PathBuf>,
init: O,
read: impl FnMut(Result<WatchFile>) -> Result<Option<O>, ER> + Send + 'static,
write: impl FnMut(O, Result<WriteFile>) -> Result<(), EW> + Send + 'static,
) -> (Var<O>, Var<S>)where
O: VarValue,
S: WatcherSyncStatus<ER, EW>,
pub fn sync_status<O, S, ER, EW>(
&self,
file: impl Into<PathBuf>,
init: O,
read: impl FnMut(Result<WatchFile>) -> Result<Option<O>, ER> + Send + 'static,
write: impl FnMut(O, Result<WriteFile>) -> Result<(), EW> + Send + 'static,
) -> (Var<O>, Var<S>)where
O: VarValue,
S: WatcherSyncStatus<ER, EW>,
Same operation as sync but also tracks the operation status in a second var.
The status variable is set to WatcherReadStatus::reading as soon as read starts and
is set to WatcherReadStatus::idle when read returns. If read returns a value the status
only updates to idle when the new sync value is available, or because read the same value.
The status variable is set to WatcherSyncStatus::writing as soon as it updates and
is set to WatcherReadStatus::idle only when the new sync value is available, either
by update or because read the same value.
Sourcepub fn on_file_changed(
&self,
file: impl Into<PathBuf>,
handler: Handler<FsChangesArgs>,
) -> EventHandle
pub fn on_file_changed( &self, file: impl Into<PathBuf>, handler: Handler<FsChangesArgs>, ) -> EventHandle
Watch file and calls handler every time it changes.
Note that the handler is blocking, use async_hn! and task::wait to run IO without
blocking the app.
Sourcepub fn on_dir_changed(
&self,
dir: impl Into<PathBuf>,
recursive: bool,
handler: Handler<FsChangesArgs>,
) -> EventHandle
pub fn on_dir_changed( &self, dir: impl Into<PathBuf>, recursive: bool, handler: Handler<FsChangesArgs>, ) -> EventHandle
Watch dir and calls handler every time something inside it changes.
Note that the handler is blocking, use async_hn! and task::wait to run IO without
blocking the app.
Sourcepub fn annotate(&self, note: Arc<dyn FsChangeNote>) -> FsChangeNoteHandle
pub fn annotate(&self, note: Arc<dyn FsChangeNote>) -> FsChangeNoteHandle
Push a note that will be cloned on all subsequent change events until the returned handle is dropped.
This can be used to tag all events that happened over a period of time, something you can’t do just by receiving the events due to async delays caused by debounce.
Note that the underlying system events the notify crate uses are not guaranteed to be synchronous.
Auto Trait Implementations§
impl Freeze for WATCHER
impl RefUnwindSafe for WATCHER
impl Send for WATCHER
impl Sync for WATCHER
impl Unpin for WATCHER
impl UnwindSafe for WATCHER
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more