A batch call for a store that writes a key's record in two dependent conditional writes: commit the folded state (fold.write, fenced on the state read), then project it into its read-side view (project, fenced on the committed record being as committed). The record says whether its projection is pending (pending), so a projection that did not happen, because the process failed or died between the writes, is finished later by resume, from the store, by any process. Nothing is kept between calls: the marker lives in the store (see docs/decisions/0014).
The view may be one object per record, written whole by project, or one row per entry, each its own write (see docs/decisions/0015). In either case project answers with what it left pending: nothing, or the entries whose row is not in the view, each with why. An input whose row is in the view when the call returns is ProjectedWrite.Outcome.Projected; any other is ProjectedWrite.Outcome.Committed, carrying why: it is durable, and the view may or may not include it yet. The call fails only when the commit is not known to have happened, and retrying it is then safe, because step answers inputs already applied; a failed projection is reported, not failed, because the inputs are durable (see docs/decisions/0006).
Use it as the call and the extract of Ferry.perKey, like FoldWrite:
val write = ProjectedWrite(FoldWrite(_.id, store.read, apply, store.commit, policy), pending, store.projectRows)
Ferry.perKey(config, (e: Entry) => e.entity)(write.call)(write.outcome)
Value parameters
- fold
-
The commit phase:
readreads the record, including its fence and its projection marker;stepreturns the state the commit stores, for whichpendingholds exactly when there is something to project;writeis the commit. The commit must never move the stored marker backwards: either it leaves the marker as stored, or it is fenced on the whole record read, marker included.retryapplies to the commit, and to resume after a first projection attempt failed; that first attempt's error is not passed to it. - pending
-
Whether a state, as read or as committed, has a projection to write. It must be pure.
- project
-
Writes the view of
stateand clears its marker. For a view of one object: writes it only if the store still holdsstate, fence and marker alike, fails otherwise, and answersProjection.complete; see ProjectedWrite.wholeRecord. For a view of one row per entry: writes each missing row, each write idempotent (a row already present is present, not an error); clears the marker only when every row is present, and only if the store still holdsstate; answers the entries still pending, each with why. It derives rows and ids fromstatealone: resume has no inputs. A failure means no verdict: the call re-reads and retries it withfold.retry. A verdict with entries pending is final for the call; the store owns its per-row retries.
Attributes
- Companion
- object
- Source
- ProjectedWrite.scala
- Graph
-
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass Any