observe_filestore/2

Resolve managed file storage operations. Records are defined in zotonic_file.hrl.

Type: first.

#filestore{} properties:

  • action: lookup, exists, upload, delete, delete_status, cancel_delete, purge_previews, cafs_adopt, or cafs_retire.
  • path: path relative to the site's files directory, such as archive/example.jpg. Deletion and deletion-status requests also accept {prefix, Prefix}.
  • local_path: optional local filename used by lookup to prefer a retained local copy.
  • mime: optional MIME type for upload queue metadata.
  • target_path: canonical CAFS path for cafs_adopt and cafs_retire.
  • older_than: timestamp text used by purge_previews as a fixed cutoff.
  • filename: optional filename; the standard filestore handler does not use this field.

Return values depend on the action:

  • lookup: {ok, {filename, Filename, StoreEntry}} or {ok, {filezcache, Pid, StoreEntry}}. StoreEntry is a map of backend metadata. A cache miss may start a download. Return undefined to fall back to local storage or another observer; it does not establish that the remote file is absent.
  • exists: read-only registry check, without network I/O or cache writes. Return true for a non-deleted entry without a recorded read error, false if absent, or {error, Reason} if availability is uncertain. This is not a remote probe.
  • upload: ok after queueing the upload, or {error, Reason}. This does not transfer file bytes. Queue insertion must participate in the caller's transaction.
  • delete: ok after marking matching entries for delayed deletion, or an error. This does not confirm remote absence. Repeated requests must preserve retention.
  • cafs_adopt: register an existing remote original at target_path without downloading it. Return ok or {error, Reason}. The caller holds the CAFS object lock and the handler must use the caller's transaction. The standard backend retargets the registry entry, retaining its remote URL; the caller must attach the logical filename in that same transaction.
  • cafs_retire: retire the redundant legacy path only once target_path is healthy. Schedule normal retained deletion for redundant remote objects. Return ok or {error, Reason}; queued legacy uploads must finish first. Use the caller's transaction.
  • delete_status: request delayed deletion and return absent only when neither remote entries nor queued uploads remain. Return pending while work remains, or {error, Reason} when unavailable or read-only. Exact paths and prefixes are supported. Repeated requests must preserve retention deadlines.
  • purge_previews: delete a bounded batch of queued resizer uploads and mark remote generated previews for deletion, restricted to preview/ and the older_than cutoff. Never delete archive/preview/ images or medium originals. Return pending while more batches may remain, ok once remote deletion is queued, or {error, Reason}. Physical deletion follows backend retention. CAFS derivatives are handled separately by their reference-aware collector.
  • cancel_delete: true when an undispatched deletion is cancelled or the path is absent; false once deletion may be in flight. Locking and cancellation must participate in the caller's transaction. An error is not confirmation of cancellation.

Return undefined for unhandled requests. A missing handler does not confirm cancellation or remote absence. Backends persist the internal site.filestore_used marker before accepting files. Core cleanup uses z_file_request:delete_remote/2 to distinguish local-only sites from an unavailable previously used backend.

Use a direct module observer for transaction-sensitive operations; passing work to a separate process must not lose the caller's transaction or its locks. See module#mod_filestore and model#cafs for storage and retention behavior.

Edit on GitHub

Observed by

Modules

mod_filestore

Store uploaded media and generated previews on S3-compatible storage, FTP/FTPS, or WebDAV. Zotonic keeps a database registry of remote files and serves them…