Пример #1
0
        /// <summary>
        /// Loads a clean copy of the model and passes it to the given
        /// block, which should apply changes to that model that can
        /// be retried from scratch multiple times until successful.
        ///
        /// This method will return the final state of the saved model.
        /// The caller should use this afterward, instead of the instance
        /// it had passed in to the call.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="block">The block.</param>
        /// <returns>the latest version of the model provided to the method</returns>
        public virtual T UpdateDocumentWithRetry(T model, Action <T> block)
        {
            var documentKey      = model.Key;
            var success          = false;
            T   documentToReturn = null;

            while (!success)
            {
                // load a clean copy of the document
                var latestDocument = GetDocument(documentKey);
                // if we were unable to find a document then create the document and
                // return the latest version of the document to the caller
                if (latestDocument == null)
                {
                    return(CreateDocument(model));
                }

                // pass the latest document to the given block so the latest changes can be applied
                if (block != null)
                {
                    block(latestDocument);
                }

                latestDocument.Version  += 1;
                latestDocument.UpdatedAt = SetUpdatedAtWithNoTimeTravel(model.UpdatedAt);
                var latestDocumentJson = latestDocument.ToJson();
                var storeResult        = Client.ExecuteCas(StoreMode.Replace, latestDocument.Key, latestDocumentJson,
                                                           latestDocument.CasValue);
                if (!storeResult.Success)
                {
                    continue;
                }

                documentToReturn = latestDocument;
                success          = true;
            }

            return(documentToReturn);
        }