-
Notifications
You must be signed in to change notification settings - Fork 37
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
(do not merge yet) Erase generic parameter by boxing Storage as trait object #113
Conversation
I think it would be even nicer if the generic argument would be removed from the Storage trait alltogether and instead each of the storages (tree, bitfield, data, keypair etc) would instead be boxed trait objects. This would also allow to use different backends for different storages. This is possible in NodeJS hypercore and allows for some nice addons/features. However, I could not find a way to make that work, because:
I don't know if there is a clean workaround for this. If there is, this would be my preferred option. If there is not, I propose to go forward with the implementation as in this PR. Also, this PR could be an intermediate step (allowing different storages within the |
@Frando I've rebased against master, introducing all changes that were pending. Try to pull again the branch when you come back. |
@Frando tests are passing, and I ended up exposing I have not considered the Public API yet, I've only focused on making it pass. I will try to remove the extra generic argument as you mentioned. Wish me luck hehe |
why not just box |
I'm documenting some of the discussion from IRC based on the suggestion from @khodzha to use the async traits. This does allow the RandomAccessStorage to become a trait object and to be boxed. With that, it is possible to write the additional methods on top of That would be yet another breaking change on This first attempt is compiler-error-driven and I have no much idea if that is enough for what hypercore needs. It would be great to try this out with a fork of |
I would even wonder if we do need those extra random_access_methods on the trait or if all of those could be provided as extension methods based on the underlying traits, like the |
Maybe random_access_storage could also take sync structs if we convert them to async like smol does for reader and writers: https://docs.rs/smol/0.1.18/smol/fn.reader.html |
This removes the generic argument from the Feed struct, making it simpler to work with. Instead, the Storage is internally put into a Box<dyn DynStorage>, where DynStorage is an async trait with the public Storage functions.
I rebased this against master today and have forced-push this PR so that CI can run. I had some git rebase foo which makes the history a little ugly. The old branch before the rebase is also pushed to I also added a test that adds Send to the DynStorage trait - I'm still playing around how to not have to worry about the trait objects at other places. |
Closed as implemented with #139. |
Currently, the
Feed
struct is generic overT: RandomAccess<Error = Box<dyn std::error::Error + Send + Sync>> + Debug + Send
. This means that the generic type has to be carried through all code that works withFeed
. This also means it's not currently possible to have e.g. aHashMap that has
Feeds that use different
RandomAccess` storages (e.g. disk and in-memory).In this (unfinished) PR this generic type argument is removed. Instead, internally the
Feed
has a boxedDynStorage
trait object that has all public methods of theStorage
struct (storage module).Thus, the generic type is erased for upstream uses!
This PR is unfinished. Signatures of the tests have to be changed. Also I didn't think fully think through what parts of this should be exposed as public APIs. Maybe instead of changing all tests (apart from removing the trait argument) we can also rename the
DynStorage
in this PR toStorage
and thus keep the storage API mostly the same, not sure. I think this would need type ascriptions though that's why I went for the public functions to create new storage instances.@bltavares please feal free to continue here and also push directly to this branch! Not sure when I find the time to get back to this.
Checklist
DynStorage
vsStorage
vs public functionsstorage_memory
andstorage_disk
Context
See #109 for initial motivation
Semver Changes
Major, because the generic type argument is removed. Likely release together with the async change (this PR also is on top of the async branch).