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 a found (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

This is an "extended IO-list", that allows atoms as well as binaries to occur either on their own or embedded in a list or deep list. The intent of this is to accept any file name that can be used by the standard library module file, as well as any normal IO-list, and any list that is formed by combining such fragments.
A monitor reference.
A list of options.
A reference to a running server. See gen_server:call/3 for more information.

Functions

Automonitors the specified path. Returns the monitor reference as well as the monitored path as a binary.

Deletes the specified monitor. This can only be done by the process that created the monitor.
Removes the directory path from the specified monitor. This can only be done by the process that created the monitor.
Removes the file path from the specified monitor. This can only be done by the process that created the monitor.
Returns the current polling interval.

Monitors the specified directory path. Returns the monitor reference as well as the monitored path as a binary.

Monitors the specified file path. Returns the monitor reference as well as the monitored path as a binary.

Flattens the given path to a single binary.
Sets the polling interval. Units are in milliseconds.

Equivalent to start([]).

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([]).

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).

Stops the specified server.

Link to this section Types

-type 
This is an "extended IO-list", that allows atoms as well as binaries to occur either on their own or embedded in a list or deep list. The intent of this is to accept any file name that can be used by the standard library module file, as well as any normal IO-list, and any list that is formed by combining such fragments.
-type 
A monitor reference.
-type 
A list of options.
Link to this type

server_ref/0

-type 
A reference to a running server. See gen_server:call/3 for more information.

Link to this section Functions

Link to this function

automonitor(Path)

Equivalent to automonitor(Path, []).

Link to this function

automonitor(Path, Opts)

Equivalent to automonitor(file_monitor, Path, Opts).

Link to this function

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.

Equivalent to demonitor(file_monitor, Ref).

Link to this function

demonitor(Server, Ref)

Deletes the specified monitor. This can only be done by the process that created the monitor.
Link to this function

demonitor_dir(Path, Ref)

Equivalent to demonitor_dir(file_monitor, Path, Ref).

Link to this function

demonitor_dir(Server, Path, Ref)

Removes the directory path from the specified monitor. This can only be done by the process that created the monitor.
Link to this function

demonitor_file(Path, Ref)

Equivalent to demonitor_file(file_monitor, Path, Ref).

Link to this function

demonitor_file(Server, Path, Ref)

Removes the file path from the specified monitor. This can only be done by the process that created the monitor.

Equivalent to get_interval(file_monitor).

Link to this function

get_interval(Server)

Returns the current polling interval.
Link to this function

monitor_dir(Path)

Equivalent to monitor_dir(Path, []).

Link to this function

monitor_dir(Path, Opts)

Equivalent to monitor_dir(file_monitor, Path, Opts).

Link to this function

monitor_dir(Server, Path, Opts)

Monitors the specified directory path. Returns the monitor reference as well as the monitored path as a binary.

Options: see monitor_file/3.
Link to this function

monitor_file(Path)

Equivalent to monitor_file(Path, []).

Link to this function

monitor_file(Path, Opts)

Equivalent to monitor_file(file_monitor, Path, Opts).

Link to this function

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.
Link to this function

normalize_path(Path)

Flattens the given path to a single binary.
Link to this function

set_interval(Time)

Equivalent to set_interval(file_monitor, Time).

Link to this function

set_interval(Server, Time)

Sets the polling interval. Units are in milliseconds.

Equivalent to start([]).

Equivalent to start({local, file_monitor}, Options).

Link to this function

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.

Options:
  • {interval, Milliseconds::integer()}

Equivalent to start_link([]).

Link to this function

start_link(Options)

Equivalent to start_link({local, file_monitor}, Options).

Link to this function

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.

Options: see start/2.

Equivalent to stop(file_monitor).

Stops the specified server.