
Hold a store's lock while an application changes it
Source:R/artifact-store.R
graft_with_store_lock.RdRun code while holding the store's lock, so an application can make a
change that spans several Graft calls without another process writing in
between. Every write to a local store holds this lock shared, and
graft_manifest(), graft_plan_replacement(), graft_replace(),
graft_backup(), and graft_restore() hold it exclusively.
Arguments
- store
A handle returned by
graft_store()orgraft_store_postgres().- code
Code to run while the lock is held.
- exclusive
TRUEto keep every other process out of the store,FALSEto share the lock with other writers.
Value
The value of code. If the lock is not free within the store's
lock_timeout, an error of class graft_store_busy_error is signalled
and code is not run. A store this process cannot write has no lock it
can take, so holding it is an error too.
Details
A host that forgets an artifact by building a replacement store holds the old store's lock exclusively while it plans, copies, and switches to the replacement, and wraps each of its writes in a shared hold that first checks the store is still current. A write that was waiting on the lock then sees the switch and goes to the new store instead of the retired one.
Graft calls inside code run under the lock already held. An exclusive
hold cannot be taken inside a shared one. PostgreSQL stores run code
directly: the host's transaction and scope lock already serialize it.
Examples
path <- tempfile("artifacts-")
store <- graft_store(path, create = TRUE)
ref <- graft_with_store_lock(store, graft_save(store, "Evidence", "report"))
graft_read(store, ref)@data
#> [1] "Evidence"
unlink(path, recursive = TRUE)