zotonic_filewatcher_monitor (zotonic_filewatcher v1.0.0-rc.14)
Erlang file monitoring service
The behaviour of this service is inspired by the open source FAM daemon (http://oss.sgi.com/projects/fam/). It allows file system paths to be monitored, so that a message will be sent to the client process whenever a status change is detected. Currently, the only supported method of detection is by regular polling by the server. While it is not optimal, polling has less overhead than might be expected, and is portable across platforms. The polling interval can be adjusted; by default the server polls all monitored paths every 5 seconds. Recursive (automatic) monitoring is supported. The server keeps track of its client processes, and removes all their monitors if they should die.
event-messages
Event messages
When a new monitor is set up, or a change is detected, an event message is sent to the client. These have the following general form:{file_monitor, Ref::monitor(), Event}
where Ref
is the monitor reference returned when the monitor was set up, and Event
is one of the following:{found, Path::binary(), Type, Info::#file_info{}, Entries::[{added | deleted, Name::binary()}]}
{changed, Path::binary(), Type, Info::#file_info{}, Entries::[{added | deleted, Name::binary()}]}
{error, Path::binary(), Type, PosixError::atom()}
where Path
is the watched path (as a binary), Type
is the type of monitoring being performed (either file
or directory
), Info
is a file_info
record as defined in kernel/include/file.hrl
, and Entries
is a list of tuples {added, binary()}
and {deleted, binary()}
describing changes to the directory entries if Type
is directory
, otherwise this is always the empty list. For a found
event, all entries are {added, Name}
.
A found
event is sent when a monitor is initially set up, if the path can be read. After that, whenever a change in status is detected, a changed
event is sent. If the file does not exist or could for some other reason not be accessed, an error
event is sent (both initially and for subsequent changes). In other words, the first event for a path is always either found
or error
, and later events are either changed
or error
.
Detection of file type changes
If the object found at a path changes type in the interval between two polls, for example if a directory is replaced by a file with the same name, or vice versa, the file monitor server will detect this and dispatch an enoent
error event before the new status event. A client can thus rely on always seeing the old file disappear before any change that reports a different file type.
monitoring-types
Monitoring types
There are two ways in which a path can be monitored: as a file
, meaning that we are interested only in the object found at that path, or as a directory
, meaning that we expect the path to point to a directory, and we are also interested in the list of entries of that directory.
If a path is monitored as a directory, and the object at the path exists but is not a directory, an enotdir
error event will be generated. An existing directory can however both be monitored as a directory and as a file - the difference is that in the latter case, the reported list of entries will always be empty.
automatic-recursive-monitoring
Automatic (recursive) monitoring
Automatic monitoring (automonitoring for short) can be used to watch a single file of any type, or a whole directory tree. The monitoring type (file
or directory
) used for any path is based on the actual type of object found at the path (directory
if the object is a readable directory, and file
otherwise). If the object is replaced by another of different type, the monitoring type will change automatically.
When a directory becomes automonitored, all of its entries will also be automatically monitored, recursively. As entries are created or deleted in an automonitored directory, they will be dynamically added or removed, respectively, from being monitored. The root path used to create the automonitor will however always remain monitored (even if the object temporarily or permanently disappears) until the server is told to delete the monitor.
The event messages sent to the client are the same as if manual monitoring was done. A newly discovered path will be reported by afound
(or possibly, by an error
event), and subsequent changes on that path are reported by changed
and error
events. If the monitoring type is changed, a new found
event is sent, and so on.
Link to this section Summary
Types
file
, as well as any normal IO-list, and any list that is formed by combining such fragments.gen_server:call/3
for more information.Functions
Equivalent to automonitor(Path, []).
Equivalent to automonitor(file_monitor, Path, Opts).
Automonitors the specified path. Returns the monitor reference as well as the monitored path as a binary.
Equivalent to demonitor(file_monitor, Ref).
Equivalent to demonitor_dir(file_monitor, Path, Ref).
Equivalent to demonitor_file(file_monitor, Path, Ref).
Equivalent to get_interval(file_monitor).
Equivalent to monitor_dir(Path, []).
Equivalent to monitor_dir(file_monitor, Path, Opts).
Monitors the specified directory path. Returns the monitor reference as well as the monitored path as a binary.
Equivalent to monitor_file(Path, []).
Equivalent to monitor_file(file_monitor, Path, Opts).
Monitors the specified file path. Returns the monitor reference as well as the monitored path as a binary.
Equivalent to set_interval(file_monitor, Time).
Equivalent to start({local, file_monitor}, Options).
Starts the server and registers it using the specified name. If the name is undefined
, the server will not be registered. See gen_server:start_link/4
for details about the return value.
Equivalent to start_link([]).
Equivalent to start_link({local, file_monitor}, Options).
Starts the server, links it to the current process, and registers it using the specified name. If the name is undefined
, the server will not be registered. See gen_server:start_link/4
for details about the return value.
Equivalent to stop(file_monitor).
Link to this section Types
filename/0
-type
file
, as well as any normal IO-list, and any list that is formed by combining such fragments.
monitor/0
-type
options/0
-type
server_ref/0
-type
gen_server:call/3
for more information.
Link to this section Functions
automonitor(Path)
Equivalent to automonitor(Path, []).
automonitor(Path, Opts)
Equivalent to automonitor(file_monitor, Path, Opts).
automonitor(Server, Path, Opts)
Automonitors the specified path. Returns the monitor reference as well as the monitored path as a binary.
Options: none at present.demonitor(Ref)
Equivalent to demonitor(file_monitor, Ref).
demonitor(Server, Ref)
demonitor_dir(Path, Ref)
Equivalent to demonitor_dir(file_monitor, Path, Ref).
demonitor_dir(Server, Path, Ref)
demonitor_file(Path, Ref)
Equivalent to demonitor_file(file_monitor, Path, Ref).
demonitor_file(Server, Path, Ref)
get_interval()
Equivalent to get_interval(file_monitor).
get_interval(Server)
monitor_dir(Path)
Equivalent to monitor_dir(Path, []).
monitor_dir(Path, Opts)
Equivalent to monitor_dir(file_monitor, Path, Opts).
monitor_dir(Server, Path, Opts)
Monitors the specified directory path. Returns the monitor reference as well as the monitored path as a binary.
Options: seemonitor_file/3
.
monitor_file(Path)
Equivalent to monitor_file(Path, []).
monitor_file(Path, Opts)
Equivalent to monitor_file(file_monitor, Path, Opts).
monitor_file(Server, Path, Opts)
Monitors the specified file path. Returns the monitor reference as well as the monitored path as a binary.
Options:{monitor, monitor()}
: specifies a reference for identifying the monitor to which the path should be added. The monitor need not already exist, but if it does, only the same process is allowed to add paths to it, and paths may not be added manually to an automonitor.
normalize_path(Path)
set_interval(Time)
Equivalent to set_interval(file_monitor, Time).
set_interval(Server, Time)
start()
Equivalent to start([]).
start(Options)
Equivalent to start({local, file_monitor}, Options).
start(Name, Options)
Starts the server and registers it using the specified name. If the name is undefined
, the server will not be registered. See gen_server:start_link/4
for details about the return value.
{interval, Milliseconds::integer()}
start_link()
Equivalent to start_link([]).
start_link(Options)
Equivalent to start_link({local, file_monitor}, Options).
start_link(Name, Options)
Starts the server, links it to the current process, and registers it using the specified name. If the name is undefined
, the server will not be registered. See gen_server:start_link/4
for details about the return value.
start/2
.
stop()
Equivalent to stop(file_monitor).