Repository navigation
feat(cache)!: record where each release in the local registry comes from - #674
Merged
Merged
Conversation
This was referenced Nov 4, 2026
karhu
force-pushed
the
tnet-157/20-store-tools
branch
from
November 5, 2026 07:24
418eaca to
cb78c04
Compare
karhu
force-pushed
the
tnet-157/20-store-tools
branch
from
November 5, 2026 07:27
cb78c04 to
d127126
Compare
karhu
force-pushed
the
tnet-157/20-store-tools
branch
from
November 5, 2026 08:16
d127126 to
8ceb46b
Compare
karhu
force-pushed
the
tnet-157/20-store-tools
branch
from
November 5, 2026 10:57
8ceb46b to
11f48ea
Compare
karhu
force-pushed
the
tnet-157/20-store-tools
branch
2 times, most recently
from
November 9, 2026 12:23
64830da to
9964154
Compare
karhu
force-pushed
the
tnet-157/20-store-tools
branch
from
November 9, 2026 13:56
9964154 to
e88e748
Compare
karhu
force-pushed
the
tnet-157/20-store-tools
branch
from
November 9, 2026 15:06
e88e748 to
9752172
Compare
karhu
force-pushed
the
tnet-157/20-store-tools
branch
4 times, most recently
from
November 10, 2026 14:39
f79ae09 to
f3dfc71
Compare
karhu
force-pushed
the
tnet-157/20-store-tools
branch
from
November 10, 2026 15:50
f3dfc71 to
2f519b1
Compare
karhu
force-pushed
the
tnet-157/20-store-tools
branch
from
November 10, 2026 16:24
2f519b1 to
a258b3c
Compare
The local registry could not tell a copy of a release from a build of it. A copy is easy to get again from its registry, but a build can take hours or need credentials. So the timenet local commands could not delete the copies and keep the builds. The local registry now keeps a provenance record in the directory of each release, in the file .origin.json. LocalRegistry.record_origin() writes the record, and LocalRegistry.read_origin() reads it as an Origin. The record gives the kind of the release, an OriginKind: DOWNLOAD for a copy from a registry, or BUILD. It names the registry, or the backend package and its version, and it gives the time in UTC. A URL in the record loses its user info, query and fragment, so no credential lands in it. A damaged record raises TimeFFormatError, which names its first problem. A release without a record counts as built. run_plan() writes a record for each copy and each build, and TimeNet.download() for each release that it copies. copy_release() returns the releases that it copied or repaired. publish() writes no record, and a copy never carries one. Each registry names its location, and the InstalledBuilder of a dataset holds the package that builds it, with its version. A backend that no installed package declares raises TimeNetBuildError when its builder is looked up. The fake backends of timenet.testing come from the fake package timenet-testing 0. The new groups timenet local downloads and timenet local builds split the local registry by the record. A download is a copy from a registry. A build is a release that a connector built, or a release without a record. In each group, info lists the releases with their source and size, and clear deletes them. A clear never deletes a release that a release that stays needs: its payload sources, and the parents of a build. This rule holds in both directions. The command names each release that it keeps and a release that needs it. A damaged record, a damaged manifest of a release that stays, or a symlinked dataset or release folder stops the command before it deletes anything. timenet local info shows the size of the downloads and of the builds, and the prompt of timenet local clear counts the builds. In timenet.cache, clear_releases() takes the kinds to delete, OriginKind.DOWNLOAD, OriginKind.BUILD or both, and returns the releases that it keeps. It refuses an empty list of kinds with TimeFValidationError. releases_to_clear() gives the same answer without a delete. StoredRelease.kind tells the kind of a release, and StoredRelease.size() measures it on disk. The byte-count callback of the registries is now ByteCountCallback, so ProgressCallback means only the callback of progress events. BREAKING CHANGE: timenet.registry.base.ProgressCallback is now ByteCountCallback. Part of TNET-157.
Shorter docstrings for the code that this change adds or changes. Part of TNET-157.
Drop tests that cannot fail or repeat other tests, and sharpen the rest. Part of TNET-157.
…egistry in the client The coordinator used three names for the registry that its copies and builds go into: "store", "output" and "local registry". Now it uses one name, the target registry. The parameters of plan_release_build(), run_plan(), plan_steps(), plan_download(), plan_read() and read_release() are now target_registry. In the planner, _Graph.output is now target_registry, in_output() is now in_target(), and needed_in_local_registry is now needed_in_target. The docstrings and comments say "the target registry" in place of "the output" and "the store". In the client, TimeNet._store is now TimeNet._local_registry. The local variables and the parameters of the client helpers that hold it follow. In timenet-build build, the opened local registry is now local. The tests follow. In the coordinator tests, the fixtures, the variables, the test names and the case names for the registry that copies and builds go into say target_registry. Where a test means the local registry of the client, the SDK functions or the CLI, its names say local_registry. Other meanings of "store" keep their names: the store_dataset() stage of a connector, stored_releases and StoredRelease, and the parameter store of Backend.build() in the fake backends. The public names do not change, and the behavior does not change. Part of TNET-157.
karhu
force-pushed
the
tnet-157/20-store-tools
branch
from
November 10, 2026 17:41
a258b3c to
952a19d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
The Stack
This stack covers refactoring the internal logic of how releases are resolved during read, download & build, in particular also in the context of parent releases / parent datasets. On top of that it refactors the public TimeNet APIs and CLI interfaces around these actions, to streamline the behavior across them.
This PR
The store records where each release comes from, a copy or a build. The new groups
timenet local downloadsandtimenet local buildsuse the records to show and clear the copies and the builds apart.Details
The store did not know a copy from a build. A copy is easy to get again from its registry, but a build can take hours or need credentials. So a
timenet localcommand deleted either every release in the store or none..origin.json: copy or build, the registry or the backend package with its version, and the time in UTC. A URL in the record loses its user info, query and fragment.run_plan()records each copy and each build.TimeNet.download()records each release that it copies.copy_release()returns the releases that it copied or repaired.BaseRegistry.locationnames each registry in a record. The newInstalledBuilder.packagenames the package that builds a dataset.timenet local downloadsandtimenet local buildssplit the store by the record. A download is a copy from a registry. A build is a release that a connector built, or a release without a record. Each group hasinfoandclear, and each of these commands takes--local-registry.infolists the releases of the group with the source and the size of each. The source is the registry of a download, or the package of a build.cleardeletes the releases of the group, but it keeps each one that a remaining release needs. It walks from each release that stays to the releases that it needs: the payload sources of a release, and the parents of a build. So the rule holds in both directions.local downloads clearkeeps a download that a build needs, andlocal builds clearkeeps a build that a download needs. A warning names each kept release and a release that needs it.timenet local infoshows the count and the size of the downloads and of the builds, instead of the whole store.timenet local clearstill deletes every release, and its prompt counts the builds.timenet.cache,clear_releases(store, *, kinds)takes the kinds to delete,"download","build"or both. Its result also names each kept release as aKeptRelease.releases_to_clear()gives the same answer without a delete.StoredRelease.kindgives theReleaseKindof a release.Design decisions
local downloads clearnever deletes a release that TimeNet did not copy.timenet local clearneeds no walk, because every release goes. So a damaged manifest or a symlinked folder does not stop it.Breaking changes
clear_releases()takeskinds=, andClearedReleaseshas the new fieldkept.timenet local infoshows the downloads and the builds instead of the local registry.timenet.registry.base.ProgressCallbackis nowByteCountCallback.StoredReleasehas the new fieldorigin. TimeNet measures its size at the first read.BaseRegistry.locationis abstract, so a registry of another package must implement it.find_card()raisesTimeNetBuildErrorif no installed package declares the entry point of the backend.Stack
Changes later in the stack:
Merge message