public static void AddTaskCreateOrUpdate <TRollback, TDocument>(this RollbackAsync <TRollback> rollback, Guid docId, string partitionKey, Func <bool, TDocument, bool> isMutated, Action <TDocument> mutateRollback, AzureStorageRepository repo) where TDocument : class, ITableEntity { rollback.AddTask( (success, failure) => { return(repo.CreateOrUpdateAsync <TDocument, RollbackAsync <TRollback> .RollbackResult>(docId, partitionKey, async(created, doc, save) => { if (!isMutated(created, doc)) { return success( async() => { if (created) { await repo.DeleteAsync(doc, () => true, () => false); } }); } await save(doc); return success( async() => { if (created) { await repo.DeleteIfAsync <TDocument, bool>(docId, async(docDelete, delete) => { // TODO: Check etag if(docDelete.ET) await delete(); return true; }, () => false); return; } await repo.UpdateAsync <TDocument, bool>(docId, async(docRollback, saveRollback) => { mutateRollback(docRollback); await saveRollback(docRollback); return true; }, () => false); }); })); }); }
public static void AddTaskCheckup <TRollback, TDocument>(this RollbackAsync <TRollback> rollback, Guid docId, Func <TRollback> onDoesNotExists, AzureStorageRepository repo) where TDocument : class, ITableEntity { rollback.AddTask( async(success, failure) => { return(await repo.FindByIdAsync(docId, (TDocument doc) => success(() => 1.ToTask()), () => failure(onDoesNotExists()))); }); }
public static void AddTaskAsyncCreateOrUpdate <TRollback, TDocument>(this RollbackAsync <TRollback> rollback, Guid docId, Func <TDocument, Task <bool> > isValidAndMutate, Func <TDocument, Task <bool> > mutateRollback, Func <TRollback> onFail, AzureStorageRepository repo) where TDocument : class, ITableEntity { rollback.AddTask( (success, failure) => { return(repo.CreateOrUpdateAsync <TDocument, RollbackAsync <TRollback> .RollbackResult>(docId, async(created, doc, save) => { if (!await isValidAndMutate(doc)) { return failure(onFail()); } await save(doc); return success( async() => { if (created) { await repo.DeleteIfAsync <TDocument, bool>(docId, async(docDelete, delete) => { // TODO: Check etag if(docDelete.ET) await delete(); return true; }, () => false); return; } await repo.UpdateAsync <TDocument, bool>(docId, async(docRollback, saveRollback) => { if (await mutateRollback(docRollback)) { await saveRollback(docRollback); } return true; }, () => false); }); })); }); }
public static void AddTaskAsyncUpdate <TRollback, TDocument>(this RollbackAsync <TRollback> rollback, Guid docId, Func <TDocument, Task <bool> > mutateUpdate, Func <TDocument, Task> mutateRollback, Func <TRollback> onNotFound, AzureStorageRepository repo) where TDocument : class, ITableEntity { rollback.AddTask( async(success, failure) => { var r = await repo.UpdateAsync <TDocument, int>(docId, async(doc, save) => { if (!await mutateUpdate(doc)) { return(1); } await save(doc); return(0); }, () => - 1); if (r == 0) { return(success( async() => { await repo.UpdateAsync <TDocument, bool>(docId, async(doc, save) => { await mutateRollback(doc); await save(doc); return true; }, () => false); })); } if (r == 1) { return(success(() => true.ToTask())); } return(failure(onNotFound())); }); }
public static void AddTaskCreate <TRollback, TDocument>(this RollbackAsync <TRollback> rollback, Guid docId, string partitionKey, TDocument document, Func <TRollback> onAlreadyExists, AzureStorageRepository repo) where TDocument : class, ITableEntity { rollback.AddTask( async(success, failure) => { return(await repo.CreateAsync(docId, partitionKey, document, () => success( async() => { await repo.DeleteIfAsync <TDocument, bool>(docId, partitionKey, async(doc, delete) => { await delete(); return true; }, () => false); }), () => failure(onAlreadyExists()))); }); }
public static void AddTaskUpdate <T, TRollback, TDocument>(this RollbackAsync <T, TRollback> rollback, Guid docId, Func <TDocument, T> mutateUpdate, Func <T, TDocument, bool> mutateRollback, Func <T> ifNotFound, AzureStorageRepository repo) where TDocument : class, ITableEntity { rollback.AddTask( async(success, failure) => { var r = await repo.UpdateAsync <TDocument, Carry <T>?>(docId, async(doc, save) => { var carry = mutateUpdate(doc); await save(doc); return(new Carry <T> { carry = carry, }); }, () => default(Carry <T>?)); if (r.HasValue) { return(success(r.Value.carry, async() => { await repo.UpdateAsync <TDocument, bool>(docId, async(doc, save) => { mutateRollback(r.Value.carry, doc); await save(doc); return true; }, () => false); })); } return(success(ifNotFound(), () => ((object)null).ToTask())); }); }
public static void AddTaskUpdate <T, TRollback, TDocument>(this RollbackAsync <TRollback> rollback, Guid docId, Func < TDocument, Func <T, UpdateCallback <T> >, // Save + Success Func <UpdateCallback <T> >, // No Save + Success Func <UpdateCallback <T> >, // Reject UpdateCallback <T> > mutateUpdate, Func <T, TDocument, bool> mutateRollback, Func <TRollback> onMutateRejected, Func <TRollback> onNotFound, AzureStorageRepository repo) where TDocument : class, ITableEntity { rollback.AddTask( async(success, failure) => { var r = await repo.UpdateAsync <TDocument, UpdateCallback <T> >(docId, async(doc, save) => { var passThrough = mutateUpdate(doc, (passThroughSuccess) => UpdateCallback <T> .Save(passThroughSuccess), () => UpdateCallback <T> .SuccessNoSave(), () => UpdateCallback <T> .Reject()); if (passThrough.save) { await save(doc); } return(passThrough); }, () => UpdateCallback <T> .NotFound()); if (!r.found) { return(failure(onNotFound())); } if (!r.success) { return(failure(onMutateRejected())); } return(success( async() => { if (r.save) { await repo.UpdateAsync <TDocument, bool>(docId, async(doc, save) => { if (mutateRollback(r.t, doc)) { await save(doc); } return true; }, () => false); } // If this was not saved, there is no reason to do anything on the rollback })); }); }