-
Notifications
You must be signed in to change notification settings - Fork 417
Implement KVStore
for TestStore
, drop process_events_async_with_kv_store_sync
#4069
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
base: main
Are you sure you want to change the base?
Conversation
.. to be easier reusable by different trait implementations.
👋 Thanks for assigning @TheBlueMatt as a reviewer! |
e636a74
to
6246c04
Compare
6246c04
to
7faae86
Compare
@@ -1187,80 +1187,6 @@ fn check_and_reset_sleeper< | |||
} | |||
} | |||
|
|||
/// Async events processor that is based on [`process_events_async`] but allows for [`KVStoreSync`] to be used for | |||
/// synchronous background persistence. | |||
pub async fn process_events_async_with_kv_store_sync< |
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.
Hmm, not quite sure I understand why we want to drop this? ldk-node might not use it, but I imagine some others might? Its the equivalent of our previous async BP loop and keeping it makes upgrades easier for those who might not want to switch to partial-async-kvstore immediately?
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.
IMO it's a very odd middleground API that was introduced when the KVStoreSyncWrapper
wasn't public. I fear users might find it confusing, and just using KVStoreSyncWrapper
when needed seems way more consistent (as they'd already need to do that for some of the other types they'd hand into that method anyways).
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.
No comment. It's so little code that I think it's fine either way.
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.
IMO we should prefer users not use KVStoreSyncWrapper
directly. The docs even explicitly say "It is not necessary to use this type directly." (and I feel like we should #[doc(hidden)]
it?).
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.
Hmm, but at least in LDK Node using KVStoreSyncWrapper
was unavoidable. I can drop the drop commit if you insist, but IMO it's a pretty awkward confusing API.
lightning/src/util/test_utils.rs
Outdated
} | ||
} | ||
|
||
impl KVStore for TestStore { |
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.
I wonder if we shouldn't actually make these async? eg write the returned future to require two polls or something? Maybe its not worth it but seems like we should consider it. It feels a bit weird to have the test implementation do something that no real implementation should do.
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.
Alright, now added a fixup to do just that.
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.
Now force-pushed a further simplification, also allowing to drop the 'splitting' commit.
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.
Oh I like this double poll thing for testing. A bit too fake otherwise.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4069 +/- ##
==========================================
- Coverage 88.39% 88.37% -0.02%
==========================================
Files 177 177
Lines 131314 131518 +204
Branches 131314 131518 +204
==========================================
+ Hits 116069 116224 +155
- Misses 12596 12638 +42
- Partials 2649 2656 +7
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
lightning/src/util/test_utils.rs
Outdated
let secondary_namespace = secondary_namespace.to_string(); | ||
let key = key.to_string(); | ||
let inner = Arc::clone(&self.inner); | ||
Box::pin(async move { |
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.
Before returning this, I think we need to record the order?
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.
Or spawn_blocking and await?
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.
Or just call it because it isn't actually blocking?
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.
I don't think so, as it calls through to the inner Mutex
? Ah, actually, now that we made it actually async as of #4069 (comment), we might need to?
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.
Or just call it because it isn't actually blocking?
You mean actually async? It is now, so we might need to do the whole write-tracking thing now..
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.
Nevermind, I think now that we retrieve the result sync again (while acquiring the inner Mutex
), we should be good ordering-wise?
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.
Yes I think it's good now
7faae86
to
3ef76a5
Compare
We implement the async `KVStore` trait for `TestStore`. This is mostly useful in LDK Node tests, where we use `TestStore` and we now require all stores to implement both variants.
3ef76a5
to
9df68fc
Compare
9df68fc
to
3dc60fd
Compare
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.
I understand this is going to be used in ldk-node, but I don't think any of the async code is hit in ldk itself. It's basically dead code within that scope. Test coverage of test code is maybe a bit over the top?
@@ -1187,80 +1187,6 @@ fn check_and_reset_sleeper< | |||
} | |||
} | |||
|
|||
/// Async events processor that is based on [`process_events_async`] but allows for [`KVStoreSync`] to be used for | |||
/// synchronous background persistence. | |||
pub async fn process_events_async_with_kv_store_sync< |
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.
No comment. It's so little code that I think it's fine either way.
lightning/src/util/test_utils.rs
Outdated
let secondary_namespace = secondary_namespace.to_string(); | ||
let key = key.to_string(); | ||
let inner = Arc::clone(&self.inner); | ||
Box::pin(async move { |
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.
Yes I think it's good now
lightning/src/util/test_utils.rs
Outdated
} | ||
} | ||
|
||
impl KVStore for TestStore { |
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.
Oh I like this double poll thing for testing. A bit too fake otherwise.
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.
There's a ton of room to make TestStore
a better test, dunno if it has to happen here but if you have a minute it would be nice to make it a really good test.
let first_poll = &mut inner_lock.0; | ||
if *first_poll { | ||
*first_poll = false; | ||
core::task::Poll::Pending |
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.
OH hmm this is more complicated than I thought. Technically this is a malformed future - after we switch to Ready
we're supposed to call wake on the context. In our use it doesn't matter but...ugh. I do kinda wonder if we won't eventually want to be able to test having control over when async writes complete, it might well be useful even in testing of #4063. If its too much here then we can just skip it.
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.
OH hmm this is more complicated than I thought. Technically this is a malformed future - after we switch to
Ready
we're supposed to call wake on the context.
Ah, good point. Now added a fixup that wakes after dropping the lock.
I do kinda wonder if we won't eventually want to be able to test having control over when async writes complete, it might well be useful even in testing of #4063. If its too much here then we can just skip it.
Yeah, tbh. this PR is mostly to make lightningdevkit/ldk-node#633 compile, and not even there we'd actually currently use the async TestStore
, the implementation is just needed to fulfill the trait bounds currently. So while I agree it would be nice to upgrade TestStore
and use it to write better async-KVStore tests, it's a bit out-of-scope for this PR right now. Happy to pick it up some time in a follow-up though!
fn read( | ||
&self, primary_namespace: &str, secondary_namespace: &str, key: &str, | ||
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, io::Error>> + 'static + Send>> { | ||
let res = self.read_internal(&primary_namespace, &secondary_namespace, &key); |
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.
Hmmmmm, would be nice to be able to race reads and writes rather than always immediately completing.....
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.
Right, I agree it would be nice to eventually extend this for improved test coverage. But see above: given it's not actually used anywhere it's a bit out-of-scope here.
We previously introduced a variant of the async background processor that still could take a `KVStoreSync` implementation. This was a crutch for LDK Node which uses the async BP but still relied on `KVStoreSync` everywhere. We now update LDK Node to require also as `KVStore` implementation, allowing us to switch back to the proper `process_events_async`. Hence, we're dropping the intermediate crutch here again, as it's a weird middleground API.
3dc60fd
to
cd28a16
Compare
We implement the async
KVStore
trait forTestStore
. This is mostly useful in LDK Node tests, where we useTestStore
and we now require all stores to implement both variants.Moreover, we drop the Frankenstein-esque
process_events_async_with_kv_store_sync
which won't be necessary anymore for LDK Node.