Skip to content

Commit

Permalink
Final Stored Proc diff reduction vs 3.0 as v2
Browse files Browse the repository at this point in the history
  • Loading branch information
bartelink committed Oct 21, 2020
1 parent bc3daaa commit f4f1e1a
Showing 1 changed file with 2 additions and 12 deletions.
14 changes: 2 additions & 12 deletions src/Equinox.CosmosStore/CosmosStore.fs
Original file line number Diff line number Diff line change
Expand Up @@ -392,20 +392,16 @@ module private MicrosoftAzureCosmosWrappers =
type SyncResponse = { etag: string; n: int64; conflicts: Unfold[] }

module internal SyncStoredProc =
let [<Literal>] name = "EquinoxRollingUnfolds5" // NB need to rename/number for any breaking change
let [<Literal>] body = """
let [<Literal>] private name = "EquinoxRollingUnfolds5" // NB need to rename/number for any breaking change
let [<Literal>] private body = """
// Manages the merging of the supplied Request Batch into the stream
// 0 perform concurrency check (index=-1 -> always append; index=-2 -> check based on .etag; _ -> check .n=.index)
// High level end-states:
// 1a if there is a Tip, but are only changes to the `u`nfolds (and no `e`vents) -> update Tip only
// 1b if there is a Tip, but incoming request includes an event -> generate a batch document + create empty Tip
// 2a if stream empty, but incoming request includes an event -> generate a batch document + create empty Tip
// 2b if no current Tip, and no events being written -> the incoming `req` becomes the Tip batch
function sync(req, expIndex, expEtag) {
if (!req) throw new Error("Missing req argument");
const collectionLink = __.getSelfLink();
Expand All @@ -423,15 +419,13 @@ function sync(req, expIndex, expEtag) {
} else if (current && ((expIndex === -2 && expEtag !== current._etag) || (expIndex !== -2 && expIndex !== current.n))) {
// Where possible, we extract conflicting events from e and/or u in order to avoid another read cycle;
// yielding [] triggers the client to go loading the events itself
// if we're working based on etags, the `u`nfolds likely bear relevant info as state-bearing unfolds
response.setBody({ etag: current._etag, n: current.n, conflicts: current.u || [] });
} else {
executeUpsert(current);
}
});
if (!isAccepted) throw new Error("readDocument not Accepted");
function executeUpsert(tip) {
function callback(err, doc) {
if (err) throw err;
Expand All @@ -448,13 +442,10 @@ function sync(req, expIndex, expEtag) {
const batch = { id: tip.i.toString(), p: tip.p, i: tip.i, n: tip.n, e: tip.e }
const batchAccepted = __.createDocument(collectionLink, batch, { disableAutomaticIdGeneration: true });
if (!batchAccepted) throw new Error("Unable to remove Tip markings.");
tip.i = tip.n;
tip.e = [];
}
// TODO Carry forward `u` items not present in `batch`, together with supporting catchup events from preceding batches
// Replace all the unfolds // TODO: should remove only unfolds being superseded
tip.u = req.u;
// As we've mutated the document in a manner that can conflict with other writers, our write needs to be contingent on no competing updates having taken place
Expand All @@ -466,7 +457,6 @@ function sync(req, expIndex, expEtag) {
const batch = { id: "0", p: req.p, i: 0, n: req.e.length, e: req.e };
const batchAccepted = __.createDocument(collectionLink, batch, { disableAutomaticIdGeneration: true });
if (!batchAccepted) throw new Error("Unable to create Batch 0.");
req.i = batch.n;
req.e = [];
} else {
Expand Down

0 comments on commit f4f1e1a

Please sign in to comment.