Duplexed repository Writer
Rationale
This MR relates to the goals of &3006 (closed) and provides an abstraction for write operations to registries that must be mirrored to both the metadata database and the object storage.
Usage
The duplexed.RepositoryWriter
implements the datastore.RepositoryWriter
interface and it used much in the same way as its datastore counterpart.
This interface is implemented in general to ensure that changes to the storage manged by the storage driver are only conducted after all database operations succeed, but since these can fail independently. It's best to use a transaction so that the database can be rolled back on error and consistency between the database and object storage can be maintained.
Caveats
If the caller uses a transaction as the datastore.Queryer
they must manage the lifecycle of that transaction. A special case here beyond the typical concerns, is that if a transaction is rolled back when an error has not been returned from the duplexed.RepositoryWriter
the equivalent changes to the filesystem will not be rolled back.
The Create
and SoftDelete
methods merely pass through to the underlying datastore.RepositoryStore
. While SoftDelete
has no filesystem equivalent at all, implementing Create
does not make much sense by itself since in the filesystem these would not exist without child directories.