Skip to content

StoreReference -> <Name>StoreConfig -> <Name>Store #10766

Open
@Ericson2314

Description

Today, when we open a store, we always go directly from a StoreReference to the <name>Store data type directly, creating a (typed, per store) <name>StoreConfig merely in the process. Instead, we should also create the <name>StoreConfig as a separate step, and then create the store from it.

Here's what needs to be done for that to work:

1. Make sure every <name>StoreConfig has a (scheme, authority, params) constructor

Right now, they just have params (single argument) constructors. This is still needed for the docs, but it should not be the only option. There should also be three-argument constructors as described above.

In order for us to actually make use of the other parameters, any fields which store the scheme and authority (if they are side-effect-less!!) should be moved from the corresponding <name>Store to <name>StoreConfig. For example, host should be moved from SSHStore and LegacySSHStore to SSHStoreConfig and LegacySSHStoreConfig. (And actually we can do a dedup by again moving that field to CommonSSHStoreConfig, where both type can share it.)

2. *StoreConfig should be member not base class

Right now, every <Name>Store type has its <Name>StoreConfig as a virtual base class. This won't because Config cannot be copied/moved (due to silly reasons, but let's ignore that) so we cannot initialize a *Store from a pe-eexisting *StoreConfig.

To solve this problem we should switch from inheritance to fields. In particular, every one of these *Store -> *StoreConfig virtual base classes should become a ref<FooConfig> fooConfig;. ref<..> is a crucial choice --- it works with upcasting such that from one RootStoreConfig allocation we can create as many ref<BaseClassStoreConfig> as we need, without creating redundant fresh allocations / more configs that could get out of sync (and waste space, but that's not so bad.)

Do note that its only the *Store -> *StoreConfig edges which should become fields instead. the *StoreConfig -> *StoreConfig and *Store -> *Store edges should stay as virtual inheritance --- for now, at least ;).

3. NameStore::NameStore(ref<NameStoreConfig>) constructors

With the previous steps done, we change the actual store constructors (replacing the old ones) to not take `(scheme, authority, params), but instead take the corresponding config type (by a shared reference). This should be relatively straightforward so long as everything in the previous step was done properly.

4. openStore pure virtual method

We can create a new virtual ref<Store> openStore() = 0; method on StoreConfig itself. This method's implementations will just call the constructors we modified in the last step with shared_from_this on the <Name>StoreConfig (to get the ref<....>) with make_ref<...>(....).

This method does no work on its own (it just calls the constructors) but finishes "proving" that the (concrete, non abstract) <Name>StoreConfig and <Name>Store types are actually 1-1 --- for every store type, the constructor chooses a store config type, and for every store config type, the openStore method chooses a store type, and this is a bijection.

5. Update the store registration machinery

The store registration machinery already registers each pair of store and store config types. But we'll need to fix it to deal with the interface changes from above. Instead of trying to directly construct the store with the matching scheme, it could first construct the store config and then call openStore on that.

Actually, we should go one step further, the registration machinery should just look up the right store config type, and construct a ref<StoreConfig> then the user can construct a ref<Store> from that with our new openStore method. The registration machinery can only know about store config types, and no longer needs to know about store types at all!

Metadata

Assignees

No one assigned

    Labels

    good first issueQuick win for first-time contributorssettingsSettings, global flags, nix.confsignificantNovel ideas, large API changes, notable refactorings, issues with RFC potential, etc.storeIssues and pull requests concerning the Nix store

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions