-
-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
improve design for apis with transaction #235
Comments
We can add two structs: pub struct Transaction<'doc, T> {
inner: &'doc T,
txn: yrs::Transaction<'doc>,
}
impl<'doc, T> Transaction<'doc, T> {
pub fn new(inner: &'doc T, txn: yrs::Transaction<'doc>) -> Self {
Self { inner, txn }
}
}
pub struct TransactionMut<'doc, T> {
inner: &'doc T,
txn: yrs::TransactionMut<'doc>,
}
impl<'doc, T> TransactionMut<'doc, T> {
pub fn new(inner: &'doc T, txn: yrs::TransactionMut<'doc>) -> Self {
Self { inner, txn }
}
pub fn encode_update_v1(&self) -> Vec<u8> {
self.txn.encode_update_v1()
}
}
impl<'doc> TransactionMut<'doc, Workspace> {
pub fn create<B, F>(&mut self, block_id: B, flavor: F) -> Block
where
B: AsRef<str>,
F: AsRef<str>,
{
info!("create block: {}", block_id.as_ref());
Block::new(
&mut self.txn,
self.inner,
block_id,
flavor,
self.inner.client_id(),
)
}
}
impl<'doc> TransactionMut<'doc, Block> {
pub fn set<K, T>(&mut self, key: K, value: T)
where
K: AsRef<str>,
T: Into<Any>,
{
self.inner.set(&mut self.txn, key.as_ref(), value)
}
} And add tow methods to pub fn with_transact<T>(&self, f: impl FnOnce(crate::Transaction<'_, Self>) -> T) -> T {
f(crate::Transaction::new(self, self.doc.transact()))
}
pub fn with_transact_mut<T>(&self, f: impl FnOnce(crate::TransactionMut<'_, Self>) -> T) -> T {
f(crate::TransactionMut::new(self, self.doc.transact_mut()))
} If we want to add workspace.with_transact_mut(|mut t| {
let block = t.create(&block_id, "text");
let count = block.with_transact_mut(|mut t| {
payload
.into_iter()
.filter_map(|(key, value)| {
serde_json::from_value::<Any>(value)
.map(|value| t.set(&key, value))
.ok()
})
.count()
});
Some(((count > 0).then(|| t.encode_update_v1()), block))
}) |
It can be abstracted into a Trait.
Or block.transaction(|mut t| {}, &mut txn);
block.transaction(|mut t| {});
let transaction = block.transaction(); |
i prefer to abstract into traits Another thing that can be improved is that we need to do some error handling for transform/transact_mut -- i means switch to try_transact/try_transact_mut The transact function call try_transact in internal and unwrap it directly, this will cause thread panic in a multi-threaded environment. It may be a good choice to rewrite with_trx as an async function: // try to get transaction internally with try_transact and automatically retry
workspace.with_transact(|t| {
// do something with transaction
}).await; |
OctoBase/libs/jwst/src/workspaces/workspace.rs Lines 247 to 249 in edb3f2c
Direct unwrap is definitely wrong. Using For error handling, |
Currently all workspace/block apis require transaction, we need call the api with transaction like
block.xxx(&trx, ..)
Consider providing the Workspace/Block type encapsulated by
with_trx
, which includes trx:The text was updated successfully, but these errors were encountered: