persistence
Atomic YAML persistence with per-file locks and change watching.
SealSkin keeps its configuration in hand-editable YAML files. This module is the single place that reads and writes them so every writer gets:
- atomic replacement (temporary file in the same directory +
os.replace), - one
Lockper path so concurrent handlers never interleave, - a content hash of the last write so the file watcher can tell our own writes apart from edits made by an administrator.
A path under one of store.MOUNTS names an object the nodes of a cluster
share. While the store is this node's own files that changes nothing; with a
remote store those reads and writes go to it instead, each write conditional
on the object being as this node last read it, so two nodes never overwrite
each other unseen (store.Conflict). watch_store then stands in for the
file watcher.
attributelogger= logging.getLogger(__name__)attributeReloadCallback= Callable[[str], Awaitable[None]]funclock_for(path) -> asyncio.LockReturn the lock guarding path, creating it on first use.
parampathstrFile path (normalised with abspath).
Returns
asyncio.LockThe Lock shared by every writer of that file.
funccontent_hash(data) -> strReturn the SHA-256 hex digest of data.
paramdatabytesReturns
strfunc_shared_key(path) -> str | NoneReturn the key of path in a remote store, or None for a file read and written in place.
parampathstrReturns
str | Nonefuncread_bytes(path) -> bytes | NoneReturn the content of a file or shared object, or None when it does not exist.
parampathstrReturns
bytes | Nonefuncwrite_bytes(path, data) -> NoneAtomically write a file, or a shared object as this node last read it.
parampathstrparamdatabytesReturns
Nonefuncremove(path) -> NoneDelete a file or shared object; a missing one is not an error.
parampathstrReturns
Nonefuncexists(path) -> boolWhether a file or shared object exists.
parampathstrReturns
boolfunclist_names(directory) -> list[str]Return the names of the files or shared objects directly inside directory, sorted.
paramdirectorystrReturns
list[str]funcread_yaml(path, default=None) -> AnyLoad a YAML file.
parampathstrFile to read.
paramdefaultAny= NoneValue returned when the file does not exist or is empty.
Returns
typing.AnyThe parsed document, or default.
funcdump_yaml(data) -> strSerialise data the way every SealSkin file is written.
paramdataAnyAny YAML-serialisable structure.
Returns
strYAML text with keys in insertion order.
func_write_file(path, encoded) -> NoneReplace path with encoded through a temporary file in its directory.
parampathstrparamencodedbytesReturns
Nonefuncwrite_yaml_sync(path, data) -> NoneAtomically write data to path as YAML.
The document is written to a temporary file in the target directory and
moved into place with replace, so readers never observe a
partially written file.
parampathstrDestination file.
paramdataAnyYAML-serialisable structure.
Returns
Nonefuncwrite_yaml(path, data) -> NoneAtomically write data to path under the file's lock.
parampathstrDestination file.
paramdataAnyYAML-serialisable structure.
Returns
Nonefuncwas_written_by_us(path) -> boolTell whether the current contents of path match our last write.
parampathstrFile to check.
Returns
boolTrue when the on-disk content hash equals the hash recorded by
funcwatch_paths(targets, stop_event, debounce_ms=500) -> NoneWatch files and directories and call a callback when they change.
paramtargetsdict[str, ReloadCallback]Mapping of path (file or directory) to the coroutine function invoked with the changed path. Directory targets fire for any file inside them.
paramstop_eventasyncio.EventSet it to end the watch loop.
paramdebounce_msint= 500Quiet period before a batch of changes is reported.
Returns
Nonefuncwatch_store(targets, stop_event, interval=15.0, wake=None) -> NonePoll a remote store and call a callback when another node changed its objects.
paramtargetsdict[str, ReloadCallback]The same mapping watch_paths takes; each path is matched by
its key in the store.
paramstop_eventasyncio.EventSet it to end the loop.
paramintervalfloat= 15.0Seconds between two polls.
paramwakeasyncio.Event | None= NoneSet it to poll at once, as when a peer announces a change.
Returns
None