Allow nested transactions
davidbrochart opened this issue · 1 comments
Currently, nested transactions are not allowed because that would lead to multiple TransactionMut
on a document:
def foo(doc):
with doc.transaction():
text = doc.get_text("text")
text += ", World!"
with doc.transaction():
text = doc.get_text("text")
text += "Hello"
foo(doc) # will fail
This hurts modularity, for instance if we wanted foo
to be used independently. Now foo
has to check if there is already a transaction on the document:
def foo(doc, txn=None):
if txn is None:
with doc.transaction():
text = doc.get_text("text")
text += ", World!"
else:
text = doc.get_text("text")
text += ", World!"
with doc.transaction() as txn:
text = doc.get_text("text")
text += "Hello"
foo(doc, txn)
See an example of such a workaround in jupyter-ydoc. This is not only more complicated, but this doesn't even do what is expected: the changes in foo
are "merged" into the parent transaction, which might not be desirable because we wanted them to be grouped into their own transaction.
I think that for nested transactions to work, the context manager should only create the transaction at exit, and make the changes then. This means that every change made in the context manager should be registered first.
Actually since registering changes would not affect the data structures, querying some information about their state would not return the right result, for instance:
with doc.transaction():
text += "Hello"
if len(text) > 10: # the previous operation was actually not done yet
...
A potential solution would be to mirror every change in a "parallel" data structure (not a Y type), but I don't want to get into that.
Meanwhile, #8 allows nested transactions.