feat: minimum implementation of OnceCell - #69
Conversation
|
I adopt a different design with #66 that even if a task acquired the lock and found the value had been initialized, it would still release the semaphore so that other waited I added some logs and here are some example outputs of It ensures that after each @orthur2 Could you also help take a look? |
There was a problem hiding this comment.
Pull request overview
This PR implements a minimal asynchronous OnceCell type that ensures a value is initialized exactly once across multiple concurrent tasks. The implementation uses a semaphore-based synchronization mechanism to guarantee thread-safe lazy initialization.
Key changes:
- Added
OnceCell<T>withnew(),get(), andget_or_init()methods using semaphore synchronization - Implemented proper memory management with
Droptrait for cleanup of initialized values - Added test coverage for drop behavior and concurrent initialization scenarios
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| mea/src/once/once_cell.rs | Core implementation of OnceCell using semaphore, atomic bool, and unsafe cell for thread-safe lazy initialization |
| mea/src/once/tests.rs | Test cases covering drop semantics and concurrent multi-task initialization |
| mea/src/once/mod.rs | Module declaration exposing the once_cell submodule |
| mea/src/lib.rs | Integration of once module into library exports and compile-time trait checks |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
First of all, I also agree that Overall, this PR is mostly correct. There are some minor issues, such as inaccurate comments in multiple places — you should use /// and // appropriately. There are also some minor style-related points, for example moving Finally, I suggest adding a note in the documentation: calling |
|
@orthur2 Thanks for your valuable review, I'm addressing the comments (as well as copilot's) soon |
|
@orthur2 Comments should be addressed now, some comment style issues before were mainly related to safety comments. I also added a test for cancellation. PTAL again. BTW, I found tokio's API comment is wrong. https://docs.rs/tokio/latest/tokio/sync/struct.OnceCell.html#method.get_or_init If the operation panics, the whole application will panic as well. |
Looks great. |
Signed-off-by: tison <wander4096@gmail.com>
Signed-off-by: tison <wander4096@gmail.com>
|
Push some commits for code tidy and make I'll merge this patch and any further improvement can be made then. |
This PR only includes the very essentially asynchronous implementation of
OnceCell:newdropgetget_or_initSome differences from tokio:
const_new), theOnceCellin mea only supports shared among various tasks viaArc<OnceCell<T>>, while tokio allows the static instance.initialized()is not exposed, thegetmethod should be the alternative to check if the value is initialized with very low overhead (just an construction ofOptionof a reference)The key implementation is to use a semaphore whose permits is 1, where each
get_or_initcall could acquire 1 permit and release it at the end beforeinitialized()returns true. It means there is only 1 task that is able to set the value. Other waiting tasks could be waked by thereleaseoperation onSemaphore.TODO: once this basic implementation is accepted, I will add more methods based on it.