From 6ade6a89e60d7334d31b8486440bc99fe30cbf17 Mon Sep 17 00:00:00 2001 From: Fernando Correa de Oliveira Date: Mon, 30 Aug 2021 00:22:45 +0100 Subject: [PATCH] WiP: first test to try to resolve #507 If `red-do :transaction`'s block returns a Awaitable, it creates a new Promise that will handle the commit/rollback and does not let the sync code to call commit/rollback. Probable next steps are: - extract that logic to a transaction manager - on transaction manager add a transaction stack and methods - queue-begin - unqueue-commit - break-queue-rollback (or something like that) --- lib/Red/Do.pm6 | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/Red/Do.pm6 b/lib/Red/Do.pm6 index 21dd052a..a57471bc 100644 --- a/lib/Red/Do.pm6 +++ b/lib/Red/Do.pm6 @@ -130,9 +130,28 @@ multi red-do( *%pars where *.none.key eq "with" ) is export { my $conn = get-RED-DB.begin; - KEEP $conn.commit; - UNDO $conn.rollback; - red-do |@blocks, :$async, |%pars, :with($conn); + CATCH { + default { + UNDO $conn.rollback; + .rethrow + } + } + given red-do |@blocks, :$async, |%pars, :with($conn) { + when Promise { + start { + KEEP $conn.commit; + UNDO $conn.rollback; + .result + } + } + when !*.DEFINITE { + UNDO $conn.rollback; + $_ + } + when *.DEFINITE { + $_ + } + } } #| Receives list of pairs with connection name and block