Skip to content
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

Split Store class #5729

Open
Ericson2314 opened this issue Dec 5, 2021 · 2 comments
Open

Split Store class #5729

Ericson2314 opened this issue Dec 5, 2021 · 2 comments
Labels

Comments

@Ericson2314
Copy link
Member

The Store class is too broad. It would be nice to see it split up to separate concerns, and avoid unsupported(...) default methods.

Intuitively, we have stores than just read and write files, and store that also can do builds. The latter would have primary and secondary systems, supportedFeatures, etc. etc. in the Config class.

But it's good to think about this distinction in the context of #5025 (comment), making buildPaths a top level method that works with a variety of store for different purposes.

Now buildPaths as a top-level method is not perfect because sometimes we do want to be able to let a remote store schedule too. E.g. when there is a bunch of remote builders, many people want to send jobs to a single central scheduler and let it dispatch jobs. So we don't want to just loose the ability of today's buildPaths implementation in RemoteStore and LegacySSHStore.

That means maybe it stays a method in some class (StoreThatCanSchedule?) after all? Or is StoreThatCanSchedule really the same as StoreThatCanBuild in practice? Would LocalStore need to implement this method, or should we just downcast and use the freestanding buildPaths function if it succeeds?

I don't know the answers to these; there is a lot to think through. Perhaps there is another easier split we can start with first, to start untangling things and improve our understanding?

@Ericson2314
Copy link
Member Author

Thinking about it slightly more, I think a good first step is to split out a subclass for the GC methods. It doesn't achieve to much, but also seems much more straightforward than the issues above. That would therefore serve as a good "test run" for this sort of refactor, and still do the good work of getting rid of some unimplemented calls.

Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Mar 1, 2022
Starts progress on NixOS#5729.

The idea is that we should not have these default methods throwing
"unimplemented". This is a small step in that direction.

I kept `addTempRoot` because it is a no-op, rather than failure. Also,
as a practical matter, it is called all over the place, while doing
other tasks.
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Mar 1, 2022
Starts progress on NixOS#5729.

The idea is that we should not have these default methods throwing
"unimplemented". This is a small step in that direction.

I kept `addTempRoot` because it is a no-op, rather than failure. Also,
as a practical matter, it is called all over the place, while doing
other tasks, so the downcasting would be annoying.

Maybe in the future I could move the "real" `addTempRoot` to `GcStore`,
and the existing usecases use a `tryAddTempRoot` wrapper to downcast or
do nothing, but I wasn't sure whether that was a good idea so with a
bias to less churn I didn't do it yet.
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Mar 2, 2022
Starts progress on NixOS#5729.

The idea is that we should not have these default methods throwing
"unimplemented". This is a small step in that direction.

I kept `addTempRoot` because it is a no-op, rather than failure. Also,
as a practical matter, it is called all over the place, while doing
other tasks, so the downcasting would be annoying.

Maybe in the future I could move the "real" `addTempRoot` to `GcStore`,
and the existing usecases use a `tryAddTempRoot` wrapper to downcast or
do nothing, but I wasn't sure whether that was a good idea so with a
bias to less churn I didn't do it yet.
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Mar 3, 2022
Starts progress on NixOS#5729.

The idea is that we should not have these default methods throwing
"unimplemented". This is a small step in that direction.

I kept `addTempRoot` because it is a no-op, rather than failure. Also,
as a practical matter, it is called all over the place, while doing
other tasks, so the downcasting would be annoying.

Maybe in the future I could move the "real" `addTempRoot` to `GcStore`,
and the existing usecases use a `tryAddTempRoot` wrapper to downcast or
do nothing, but I wasn't sure whether that was a good idea so with a
bias to less churn I didn't do it yet.
@Ericson2314
Copy link
Member Author

@edolstra How do you feel on ReadStore vs WriteStore: public virtual ReadStore as a split to do have GcStore?

On one hand, I think only HttpBinaryCacheStore can't implement WriteStore, so it is not that useful for categorizing implementations. On the other hand, I think it could well be used to organize with types how store are used (e.g. substitutors can be mere ReadStores), and that as Rust roughly demonstrates this is a general useful thing to do.

Also, in longer term ReadStore vs WriteStore could fit into various authentication infrastructure. (Thinking of the nexus of https://gist.github.com/edolstra/afa5a41d4acbc0d6c8cccfede7fd4792 and CA trust maps, for example. Maybe you can subscribe to certain things one cannot read from?)

Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Mar 8, 2022
Continue progress on NixOS#5729.

Just as I hoped, this uncovered an issue: the daemon protocol is missing
a way to query build logs. This doesn't effect `unix://`, but does
effect `ssh://`. A FIXME is left for this, so we come back to it later.
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Mar 11, 2022
Continue progress on NixOS#5729.

Just as I hoped, this uncovered an issue: the daemon protocol is missing
a way to query build logs. This doesn't effect `unix://`, but does
effect `ssh://`. A FIXME is left for this, so we come back to it later.
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Mar 11, 2022
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Mar 18, 2022
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Mar 25, 2022
@stale stale bot added the stale label Nov 1, 2022
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Jan 6, 2023
Ericson2314 added a commit to Ericson2314/nix that referenced this issue Apr 13, 2023
More progress on issue NixOS#5729

`queryAllValidPaths` and `queryReferrers` were two methods that failing
`unsupported` default implementation. This is not type safe. Now, those
methods are in their own classes, and there is no more `unsupported`
default instances of them.

(I thought we could get away with one class for both, but sadly that is
not quite the case: `LocalBinaryCacheStore` and `S3BinaryCacheStore`
implement the former but the latter.)
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Apr 13, 2023
More progress on issue NixOS#5729

`queryAllValidPaths` and `queryReferrers` were two methods that failing
`unsupported` default implementation. This is not type safe. Now, those
methods are in their own classes, and there is no more `unsupported`
default instances of them.

(I thought we could get away with one class for both, but sadly that is
not quite the case: `LocalBinaryCacheStore` and `S3BinaryCacheStore`
implement the former but the latter.)
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Apr 13, 2023
More progress on issue NixOS#5729

The method trivially generalizes to be store-implementation-agnostic, in
fact.

However, we force it to continue to be unimplemented with `RemoteStore`
and `LegacySSHStore` because the implementation we'd get via the
generalization is probably not the one users expect. This keeps our
hands untied to do it right going forward.

For more about the tension between the scheduler logic being
store-type-agnostic and remote stores doing their own scheduling, see
issues NixOS#5025 and NixOS#5056.
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Apr 13, 2023
More progress on issue NixOS#5729.

Instead of having it by the default method in `Store` itself, have it be
the implementation in `DummyStore` and `LegacySSHStore`. Then just the
implementations which fail to provide the method pay the "penalty" of
dealing with the icky `unimplemented` function for non-compliance.

Combined with my other recent PRs, this finally makes `Store` have no
`unsupported` calls!
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Apr 14, 2023
More progress on issue NixOS#5729

The method trivially generalizes to be store-implementation-agnostic, in
fact.

However, we force it to continue to be unimplemented with `RemoteStore`
and `LegacySSHStore` because the implementation we'd get via the
generalization is probably not the one users expect. This keeps our
hands untied to do it right going forward.

For more about the tension between the scheduler logic being
store-type-agnostic and remote stores doing their own scheduling, see
issues NixOS#5025 and NixOS#5056.
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Apr 15, 2023
More progress on issue NixOS#5729

`queryAllValidPaths` and `queryReferrers` were two methods that failing
`unsupported` default implementation. This is not type safe. Now, those
methods are in their own classes, and there is no more `unsupported`
default instances of them.

(I thought we could get away with one class for both, but sadly that is
not quite the case: `LocalBinaryCacheStore` and `S3BinaryCacheStore`
implement the former but the latter.)

`require<StoreSubClass` should only be used in "entry point" code, like
the UI or protocol handlers. That means the usage we made in `misc.cc`
is no good. That will be fixed in the next commit.
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue May 10, 2023
More progress on issue NixOS#5729

`queryAllValidPaths` and `queryReferrers` were two methods that failing
`unsupported` default implementation. This is not type safe. Now, those
methods are in their own classes, and there is no more `unsupported`
default instances of them.

(I thought we could get away with one class for both, but sadly that is
not quite the case: `LocalBinaryCacheStore` and `S3BinaryCacheStore`
implement the former but the latter.)

`require<StoreSubClass` should only be used in "entry point" code, like
the UI or protocol handlers. That means the usage we made in `misc.cc`
is no good. That will be fixed in the next commit.
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Oct 25, 2023
More progress on issue NixOS#5729

`queryAllValidPaths` and `queryReferrers` were two methods that failing
`unsupported` default implementation. This is not type safe. Now, those
methods are in their own classes, and there is no more `unsupported`
default instances of them.

(I thought we could get away with one class for both, but sadly that is
not quite the case: `LocalBinaryCacheStore` and `S3BinaryCacheStore`
implement the former but the latter.)

`require<StoreSubClass` should only be used in "entry point" code, like
the UI or protocol handlers. That means the usage we made in `misc.cc`
is no good. That will be fixed in the next commit.
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Oct 31, 2023
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Nov 2, 2023
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Nov 2, 2023
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Nov 4, 2023
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Nov 13, 2023
More progress on issue NixOS#5729

`queryAllValidPaths` and `queryReferrers` were two methods that failing
`unsupported` default implementation. This is not type safe. Now, those
methods are in their own classes, and there is no more `unsupported`
default instances of them.

(I thought we could get away with one class for both, but sadly that is
not quite the case: `LocalBinaryCacheStore` and `S3BinaryCacheStore`
implement the former but the latter.)

`require<StoreSubClass` should only be used in "entry point" code, like
the UI or protocol handlers. That means the usage we made in `misc.cc`
is no good. That will be fixed in the next commit.
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Nov 30, 2023
More progress on issue NixOS#5729

`queryAllValidPaths` and `queryReferrers` were two methods that failing
`unsupported` default implementation. This is not type safe. Now, those
methods are in their own classes, and there is no more `unsupported`
default instances of them.

(I thought we could get away with one class for both, but sadly that is
not quite the case: `LocalBinaryCacheStore` and `S3BinaryCacheStore`
implement the former but the latter.)

`require<StoreSubClass` should only be used in "entry point" code, like
the UI or protocol handlers. That means the usage we made in `misc.cc`
is no good. That will be fixed in the next commit.
github-actions bot pushed a commit that referenced this issue Dec 7, 2023
More progress on #5729.

(cherry picked from commit e97ac09)
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Dec 7, 2023
More progress on NixOS#5729.

(cherry picked from commit e97ac09)
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Dec 20, 2023
More progress on issue NixOS#5729

`queryAllValidPaths` and `queryReferrers` were two methods that failing
`unsupported` default implementation. This is not type safe. Now, those
methods are in their own classes, and there is no more `unsupported`
default instances of them.

(I thought we could get away with one class for both, but sadly that is
not quite the case: `LocalBinaryCacheStore` and `S3BinaryCacheStore`
implement the former but the latter.)

`require<StoreSubClass` should only be used in "entry point" code, like
the UI or protocol handlers. That means the usage we made in `misc.cc`
is no good. That will be fixed in the next commit.
Ericson2314 added a commit to obsidiansystems/nix that referenced this issue Jan 18, 2024
…rchy

Instead of having it be the default method in `Store` itself, have it be
the implementation in `DummyStore` and `LegacySSHStore`. Then just the
implementations which fail to provide the method pay the "penalty" of
dealing with the icky `unimplemented` function for non-compliance.

Picks up where NixOS#8217. Getting close to no `unsupported` in the `Store`
interface itself!

More progress on issue NixOS#5729.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant