From b0b2f07ec11141eebee8bdb6ed73d232c33876ef Mon Sep 17 00:00:00 2001 From: Stefan Wehrmeyer Date: Wed, 4 Oct 2023 14:39:33 +0200 Subject: [PATCH] Commit transactions from callback --- src/y_doc.rs | 14 +++++++++++++- tests/test_y_transaction.py | 8 ++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/y_doc.rs b/src/y_doc.rs index 918078d..a6d77e5 100644 --- a/src/y_doc.rs +++ b/src/y_doc.rs @@ -79,6 +79,16 @@ impl YDocInner { txn } + pub fn commit_transaction(&mut self) { + if let Some(weak_txn) = &self.txn { + if let Some(txn) = weak_txn.upgrade() { + let mut txn = txn.borrow_mut(); + txn.commit(); + } + } + self.txn = None; + } + pub fn transact_mut(&self, f: F) -> R where F: FnOnce(&mut YTransactionInner) -> R, @@ -200,7 +210,9 @@ impl YDoc { let args = PyTuple::new(py, vec![txn.into_py(py)]); callback.call(py, args, None) }); - self.0.borrow_mut().txn = None; + // Make transaction commit after callback returns + let mut doc = self.0.borrow_mut(); + doc.commit_transaction(); result } diff --git a/tests/test_y_transaction.py b/tests/test_y_transaction.py index 0f4c225..2584f50 100644 --- a/tests/test_y_transaction.py +++ b/tests/test_y_transaction.py @@ -35,6 +35,14 @@ def test_transaction_already_committed(): txn.commit() assert str(excinfo.value) == "Transaction already committed!" + # Try smuggling transaction out of callback and reusing it + smuggle = {} + doc.transact(lambda txn: smuggle.update({"txn": txn})) + with pytest.raises(AssertionError) as excinfo: + text.extend(smuggle["txn"], "Bug") + assert str(excinfo.value) == "Transaction already committed!" + assert str(text) == "HelloBug" + def test_document_modification_during_transaction(): doc = Y.YDoc()