-
Notifications
You must be signed in to change notification settings - Fork 21
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
feat(foundationdb): introduce db_run #73
Conversation
Pull Request Test Coverage Report for Build 3143598070
💛 - Coveralls |
Codecov ReportBase: 82.74% // Head: 82.07% // Decreases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## main #73 +/- ##
==========================================
- Coverage 82.74% 82.07% -0.68%
==========================================
Files 26 26
Lines 4956 5082 +126
==========================================
+ Hits 4101 4171 +70
- Misses 855 911 +56
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good, it's a nice tradeoff
About the panic behavior. GAT is around the corner (next stable release) so I might give a shot at writing a more user friendly transact method but that would not change the fact that it's a &Transaction that is manipulated inside the closure. I wonder, what was the pain of manipulating &Transaction, cause I remember having a whole object db engine (multithreaded) inside the closure and that was not a big problem. Still a few |
About that point: "find a way to use the borrow-checker to avoid the Arc::try_unwrap during on_error methods." No lifetime, no way at compile time to prove you are the only remaining owner of the transaction. |
I am reworking the error from db-run to include all errors that can be thrown |
What do you think @Speedy37 about the new error? |
Forgot a panic, will push another commit |
FdbBindingError::DirectoryError(directory_error) => { | ||
if let DirectoryError::FdbError(e) = directory_error { | ||
Some(*e) | ||
} else { | ||
None | ||
} | ||
} | ||
FdbBindingError::HcaError(hca_error) => { | ||
if let HcaError::FdbError(e) = hca_error { | ||
Some(*e) | ||
} else { | ||
None | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FdbBindingError::DirectoryError(directory_error) => { | |
if let DirectoryError::FdbError(e) = directory_error { | |
Some(*e) | |
} else { | |
None | |
} | |
} | |
FdbBindingError::HcaError(hca_error) => { | |
if let HcaError::FdbError(e) = hca_error { | |
Some(*e) | |
} else { | |
None | |
} | |
} | |
FdbBindingError::DirectoryError(DirectoryError::FdbError(e)) = > Some(*e), | |
FdbBindingError::HcaError(HcaError::FdbError(e)) = > Some(*e), |
Looks ok to me. |
I just though that
Another impl for RetryableTransaction could be: #[derive(Clone)]
pub struct RetryableTransaction {
inner: Arc<Transaction>,
}
impl std::ops::Deref for RetryableTransaction {
type Target = Transaction;
fn deref(&self) -> &Transaction {
self.inner.deref()
}
}
impl RetryableTransaction {
pub(crate) fn new(t: Transaction) -> RetryableTransaction {
RetryableTransaction { inner: Arc::new(t) }
}
pub(crate) fn take(self) -> Result<Transaction, FdbBindingError> {
// checking weak references
if Arc::weak_count(&self.inner) != 0 {
return Err(FdbBindingError::ReferenceToTransactionKept);
}
Arc::try_unwrap(self.inner).map_err(|_| FdbBindingError::ReferenceToTransactionKept)
}
pub(crate) async fn on_error(
self,
err: FdbError,
) -> Result<Result<RetryableTransaction, FdbError>, FdbBindingError> {
Ok(self
.take()?
.on_error(err)
.await
.map(RetryableTransaction::new))
}
pub(crate) async fn commit(
self,
) -> Result<Result<TransactionCommitted, TransactionCommitError>, FdbBindingError> {
self.take()?.commit().await
}
} |
This is brilliant 🤯 This is making the code much more readable, thanks a lot @Speedy37 🙏 I think you deserve all the credits here, would you like to push a commit to my branch? Or may I include it in a commit? |
Applying the awesome suggestion from @Speedy37(Vincent Rouillé).
I integrated your proposal. Feel free to merge it @Speedy37 if you're ok with this. |
The idea is to add the
db.run
method, which is automatically handling Transaction retry.This is a second try(#54 and #60), and while I know it is not perfect, it provides a great developer experience. This method is mandatory to build effective layers with the bindings, and we are currently using it at Clever Cloud.
It is also a requirement for #70 and to open-source the simulation crate that we have internally.
A new type,
RetryableTransaction
, has been added, which is almost like a Transaction, except that:Users can still use the
transact
/transact_boxed
methods, if they want to collaborate more with the borrow-checker, at the price of a more difficult API.Remaining things to do if this gets merged:
db.run
,Arc::try_unwrap
duringon_error
methods.