Async support for the lib's modules #23
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR includes the changes required to make the entire library's modules async ready, i.e. all the modules shall implement the traits
Send&Sync.All the stores that made use of an external lib were already async ready, but SQLite, whose library doesn't fully support async code (it's
Sendbut notSync). I'd suggest leaving the store for SQLite outside the scope of this feature, or change the used library to another that wraps SQLite to beSend&Sync(the best choice is SQLx.Thus, the main change introduced in this PR affects the
struct MemoryStoreand thestruct MerkleProof.Overview of the changes
The
structs:MemoryStoreandMerkleProofhave been wrapped using a common design pattern in Rust. The formerstructdefinitions were renamed toMemoryStoreInnerandMerkleProofInner, and 2 new structs have been defined with the base namesMemoryStoreandMerkleProofthat include an only field: an instance of the inner counterpart. This way, it is quite simple to ensure thread safety, as the entire innerstructis locked by a single lock.Multiple reads are allowed, and only one writer at a time. The choice to wrap the entire
structwith a single lock is motivated by the fact that write methods modify most of the internal fields at the same time. So rather than wrap every field with its own lock, I chose wrapping the entirestruct. This should lead to a safer operation, as the risk of deadlocks gets reduced.A new error type was included to signal a lock poisoning.
Benchmarking
The changes haven't affected the overall performance of the library:
Results before the changes:
Results after the change:
The addition of leaves for the memory store has slightly lowered its performance, as expected.