tensorfs 0.3.40__tar.gz → 0.3.41__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tensorfs-0.3.40 → tensorfs-0.3.41}/Cargo.lock +2 -2
- {tensorfs-0.3.40 → tensorfs-0.3.41}/Cargo.toml +1 -1
- {tensorfs-0.3.40 → tensorfs-0.3.41}/PKG-INFO +1 -1
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/derived.rs +13 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-py/src/store.rs +6 -1
- {tensorfs-0.3.40 → tensorfs-0.3.41}/pyproject.toml +1 -1
- {tensorfs-0.3.40 → tensorfs-0.3.41}/python/tensorfs/_derived_channel.py +45 -1
- tensorfs-0.3.41/python/tensorfs/_source_channel.py +105 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/python/tensorfs/derived.py +26 -1
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/Cargo.toml +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/build.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/examples/h3-swiglu-layout.md +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/examples/optional-cache-backfill.md +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/examples/resident-conversion.md +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/examples/resident_conversion_profile.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/b64.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/bin/tfs/ckpt.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/bin/tfs/conform.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/bin/tfs/fetch.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/bin/tfs/ingest.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/bin/tfs/main.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/bin/tfs/rd.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/bin/tfs/repo.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/bin/tfs/snap.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/bin/tfs/watch.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/cache_roots.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/canon.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/capability.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/catalog.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/cbor.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/checkpoint.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/corpus.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/derived/adoption.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/derived/estimate.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/derived/graft_tests.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/derived/progress.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/derived/resume_tests.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/derived/retention.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/derived/roots.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/dtype.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/durability.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/err.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/fetch.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/fill.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/fit.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/gc.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/header.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/home.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/ids.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/ingest/carrier.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/ingest/convert.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/ingest/fingerprint.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/ingest/gguf.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/ingest/journal.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/ingest/mod.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/ingest/preflight.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/ingest/source.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/ingest/stamp.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/ingest/transaction.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/jcs.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/lib.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/limits.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/machine.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/manifest.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/meta.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/project.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/providers.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/read.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/receipt.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/reclaim.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/registry.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/relation.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/repo_cache.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/repository.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/sha256.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/source_artifact.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/spec.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/staging.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/storage.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/store.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/transport/api.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/transport/http.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/transport/hub.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/transport/ledger.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/transport/mod.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/transport/policy.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/transport/prefix.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/transport/pull.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/transport/push.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/transport/ranged.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/transport/tests.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/src/vectors.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/fetch_url_progress.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/fit.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/fixtures/repo_apply/blobs.jsonl +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/fixtures/repo_apply/expected_list.jsonl +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/fixtures/repo_apply/expected_repository.json +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/fixtures/repo_apply/expected_rows.jsonl +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/fixtures/repo_apply/header.cbor +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/fixtures/repo_apply/manifest.json +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/fixtures/repo_apply/mutation.json +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/h3_swiglu.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/home.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/import_tree.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/instrument_profiles.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/liveness.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/read_plan.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/reclaim.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/reclaim_run.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/repo_cache.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/repo_store.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/resident_admission.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/sha256_backends.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/sharded_cas.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/source_artifacts.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/source_plan.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/source_prefixes.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/source_preflight.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/staging.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/store_boundaries.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/tensor_schema.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/version.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/write_through.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-py/Cargo.toml +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-py/src/docs.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-py/src/errors.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-py/src/lib.rs +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/python/tensorfs/__init__.py +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/python/tensorfs/_ext.pyi +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/python/tensorfs/errors.py +0 -0
- {tensorfs-0.3.40 → tensorfs-0.3.41}/python/tensorfs/py.typed +0 -0
|
@@ -421,7 +421,7 @@ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
|
|
|
421
421
|
|
|
422
422
|
[[package]]
|
|
423
423
|
name = "tensorfs-core"
|
|
424
|
-
version = "0.3.
|
|
424
|
+
version = "0.3.41"
|
|
425
425
|
dependencies = [
|
|
426
426
|
"fs2",
|
|
427
427
|
"minicbor",
|
|
@@ -434,7 +434,7 @@ dependencies = [
|
|
|
434
434
|
|
|
435
435
|
[[package]]
|
|
436
436
|
name = "tensorfs-py"
|
|
437
|
-
version = "0.3.
|
|
437
|
+
version = "0.3.41"
|
|
438
438
|
dependencies = [
|
|
439
439
|
"pyo3",
|
|
440
440
|
"tensorfs-core",
|
|
@@ -2005,6 +2005,19 @@ fn inspect_retained_source(
|
|
|
2005
2005
|
code: Code::ROOT_ABSENT,
|
|
2006
2006
|
detail: "source inspection resolved no source".into(),
|
|
2007
2007
|
})?;
|
|
2008
|
+
for component in &component_names {
|
|
2009
|
+
if !source
|
|
2010
|
+
.header
|
|
2011
|
+
.components
|
|
2012
|
+
.iter()
|
|
2013
|
+
.any(|(name, _)| name == component)
|
|
2014
|
+
{
|
|
2015
|
+
return refuse(
|
|
2016
|
+
Code::MISSING_FIELD,
|
|
2017
|
+
format!("source has no component {component:?}"),
|
|
2018
|
+
);
|
|
2019
|
+
}
|
|
2020
|
+
}
|
|
2008
2021
|
let configs = config_names
|
|
2009
2022
|
.iter()
|
|
2010
2023
|
.map(|name| {
|
|
@@ -1864,7 +1864,12 @@ impl PyStore {
|
|
|
1864
1864
|
let identity = source_facts(py, std::slice::from_ref(&inspection.view))?;
|
|
1865
1865
|
out.set_item("source", identity.get_item(0)?)?;
|
|
1866
1866
|
let component_rows = PyList::empty(py);
|
|
1867
|
-
|
|
1867
|
+
// The selected fact is a normalized set. Author inspection must retain
|
|
1868
|
+
// the header's construction traversal, including nonlexical components.
|
|
1869
|
+
for (component, _) in &inspection.view.header.components {
|
|
1870
|
+
if !inspection.view.fact.components.contains(component) {
|
|
1871
|
+
continue;
|
|
1872
|
+
}
|
|
1868
1873
|
let row = PyDict::new(py);
|
|
1869
1874
|
row.set_item("name", component)?;
|
|
1870
1875
|
row.set_item(
|
|
@@ -146,6 +146,19 @@ class DerivedTransaction:
|
|
|
146
146
|
value.receipt = dict(receipt)
|
|
147
147
|
return value
|
|
148
148
|
|
|
149
|
+
@classmethod
|
|
150
|
+
def accept(cls, fd: int) -> DerivedTransaction:
|
|
151
|
+
"""Receive the owner's live-writer or validated committed-result decision."""
|
|
152
|
+
value = cls(fd)
|
|
153
|
+
receipt = value._call("receipt")
|
|
154
|
+
if receipt is not None:
|
|
155
|
+
if not isinstance(receipt, dict):
|
|
156
|
+
value.close()
|
|
157
|
+
raise ChannelRefusal("WRONG_TYPE", "native receipt must be an object")
|
|
158
|
+
value.receipt = receipt
|
|
159
|
+
value.close()
|
|
160
|
+
return value
|
|
161
|
+
|
|
149
162
|
def _open(self) -> _Channel:
|
|
150
163
|
if self._channel is None:
|
|
151
164
|
raise ChannelRefusal("TRANSACTION_CLOSED", "derived handle is closed")
|
|
@@ -406,6 +419,7 @@ def serve_derived(
|
|
|
406
419
|
check_current()
|
|
407
420
|
else:
|
|
408
421
|
if op not in (
|
|
422
|
+
"receipt",
|
|
409
423
|
"completed_parts",
|
|
410
424
|
"completed_configs",
|
|
411
425
|
"checkpoint",
|
|
@@ -418,7 +432,9 @@ def serve_derived(
|
|
|
418
432
|
_fields(frame, op, ())
|
|
419
433
|
with admit_io(op, 0):
|
|
420
434
|
check_current()
|
|
421
|
-
if op == "
|
|
435
|
+
if op == "receipt":
|
|
436
|
+
result = None
|
|
437
|
+
elif op == "completed_parts":
|
|
422
438
|
result = writer.completed_parts()
|
|
423
439
|
elif op == "completed_configs":
|
|
424
440
|
result = writer.completed_configs()
|
|
@@ -456,3 +472,31 @@ def serve_derived(
|
|
|
456
472
|
finally:
|
|
457
473
|
channel.close()
|
|
458
474
|
writer.fence()
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
def serve_derived_replay(
|
|
478
|
+
receipt: Mapping[str, Any],
|
|
479
|
+
fd: int,
|
|
480
|
+
*,
|
|
481
|
+
check_current: Callable[[], None],
|
|
482
|
+
record_receipt: Callable[[dict[str, Any]], None],
|
|
483
|
+
) -> None:
|
|
484
|
+
"""Deliver retained native custody selected by the trusted execution owner."""
|
|
485
|
+
channel = _Channel(fd)
|
|
486
|
+
try:
|
|
487
|
+
request = channel.receive()
|
|
488
|
+
if not isinstance(request, dict):
|
|
489
|
+
raise ChannelRefusal("WRONG_TYPE", "expected a receipt request")
|
|
490
|
+
_fields(request, "receipt", ())
|
|
491
|
+
check_current()
|
|
492
|
+
facts = dict(receipt)
|
|
493
|
+
record_receipt(facts)
|
|
494
|
+
channel.send({"result": facts})
|
|
495
|
+
except EOFError:
|
|
496
|
+
return
|
|
497
|
+
except Exception as exc:
|
|
498
|
+
with contextlib.suppress(OSError, EOFError):
|
|
499
|
+
channel.send({"error": str(getattr(exc, "code", "IO_FAILED")), "detail": "native receipt owner refused"})
|
|
500
|
+
raise
|
|
501
|
+
finally:
|
|
502
|
+
channel.close()
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""One exact source's bounded metadata/config channel, with no Store escape."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import contextlib
|
|
6
|
+
import threading
|
|
7
|
+
from collections.abc import Callable, Sequence
|
|
8
|
+
from typing import Any, ContextManager
|
|
9
|
+
|
|
10
|
+
from . import _ext
|
|
11
|
+
from ._derived_channel import ChannelRefusal, _Channel, _CHUNK, _METADATA, _fields
|
|
12
|
+
from .derived import Source, SourceInspection
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class SourceClient:
|
|
16
|
+
def __init__(self, fd: int, source: Source) -> None:
|
|
17
|
+
self.channel = _Channel(fd)
|
|
18
|
+
self.source = source
|
|
19
|
+
self.lock = threading.Lock()
|
|
20
|
+
|
|
21
|
+
def close(self) -> None:
|
|
22
|
+
self.channel.close()
|
|
23
|
+
|
|
24
|
+
def inspect(self, components: Sequence[str], configs: Sequence[str]) -> SourceInspection:
|
|
25
|
+
with self.lock:
|
|
26
|
+
try:
|
|
27
|
+
self.channel.send({"op": "inspect", "components": list(components), "configs": list(configs)})
|
|
28
|
+
answer = self.channel.reply()
|
|
29
|
+
if set(answer) != {"result"} or not isinstance(answer["result"], dict):
|
|
30
|
+
raise ChannelRefusal("WRONG_TYPE", "invalid source inspection response")
|
|
31
|
+
value = answer["result"]
|
|
32
|
+
total = 0
|
|
33
|
+
for config in value["configs"]:
|
|
34
|
+
length = config.pop("length")
|
|
35
|
+
if type(length) is not int or not 0 <= length <= _METADATA - total:
|
|
36
|
+
raise ChannelRefusal("SIZE_CAP", "source configurations exceed their bound")
|
|
37
|
+
total += length
|
|
38
|
+
data = bytearray(length)
|
|
39
|
+
view = memoryview(data)
|
|
40
|
+
while view:
|
|
41
|
+
block = self.channel.receive()
|
|
42
|
+
if not isinstance(block, bytes) or not block or len(block) > len(view):
|
|
43
|
+
raise ChannelRefusal("LENGTH_MISMATCH", "invalid source configuration stream")
|
|
44
|
+
view[:len(block)] = block
|
|
45
|
+
view = view[len(block):]
|
|
46
|
+
config["data"] = bytes(data)
|
|
47
|
+
result = SourceInspection.from_native(value)
|
|
48
|
+
if result.source != self.source:
|
|
49
|
+
raise ChannelRefusal("TRANSACTION_CONFLICT", "source inspection changed identity")
|
|
50
|
+
return result
|
|
51
|
+
except BaseException:
|
|
52
|
+
self.channel.close()
|
|
53
|
+
raise
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def serve_source(
|
|
57
|
+
store: _ext.Store,
|
|
58
|
+
source: Source,
|
|
59
|
+
fd: int,
|
|
60
|
+
*,
|
|
61
|
+
check_current: Callable[[], None],
|
|
62
|
+
admit_io: Callable[[], ContextManager[None]],
|
|
63
|
+
) -> None:
|
|
64
|
+
"""The owner fixes the source; the peer can only select its native metadata."""
|
|
65
|
+
channel = _Channel(fd)
|
|
66
|
+
try:
|
|
67
|
+
while True:
|
|
68
|
+
request = channel.receive()
|
|
69
|
+
if not isinstance(request, dict):
|
|
70
|
+
raise ChannelRefusal("WRONG_TYPE", "expected a source inspection")
|
|
71
|
+
_fields(request, "inspect", ("components", "configs"))
|
|
72
|
+
check_current()
|
|
73
|
+
components, configs = request["components"], request["configs"]
|
|
74
|
+
if not isinstance(components, list) or not isinstance(configs, list):
|
|
75
|
+
raise ChannelRefusal("WRONG_TYPE", "source selections must be lists")
|
|
76
|
+
with admit_io():
|
|
77
|
+
check_current()
|
|
78
|
+
if not components or not configs:
|
|
79
|
+
raw_header = store.manifest(source.manifest)["header"]
|
|
80
|
+
if raw_header is None:
|
|
81
|
+
raise ChannelRefusal("MISSING_FIELD", "source has no tensor header")
|
|
82
|
+
header = _ext.parse_header(raw_header)
|
|
83
|
+
components = components or list(header["components"])
|
|
84
|
+
configs = configs or list(header.get("configs", {}))
|
|
85
|
+
value = store.inspect_derived_source(source.manifest, source.length, components, configs)
|
|
86
|
+
check_current()
|
|
87
|
+
configuration = value["configs"]
|
|
88
|
+
metadata: dict[str, Any] = {
|
|
89
|
+
**value,
|
|
90
|
+
"configs": [{"name": row["name"], "length": len(row["data"])} for row in configuration],
|
|
91
|
+
}
|
|
92
|
+
channel.send({"result": metadata})
|
|
93
|
+
for row in configuration:
|
|
94
|
+
data = memoryview(row["data"])
|
|
95
|
+
for start in range(0, len(data), _CHUNK):
|
|
96
|
+
check_current()
|
|
97
|
+
channel.data(data[start:start+_CHUNK])
|
|
98
|
+
except EOFError:
|
|
99
|
+
return
|
|
100
|
+
except Exception as exc:
|
|
101
|
+
with contextlib.suppress(OSError, EOFError):
|
|
102
|
+
channel.send({"error": str(getattr(exc, "code", "IO_FAILED")), "detail": "source owner refused inspection"})
|
|
103
|
+
raise
|
|
104
|
+
finally:
|
|
105
|
+
channel.close()
|
|
@@ -11,7 +11,7 @@ from collections.abc import Callable, Mapping, Sequence
|
|
|
11
11
|
from dataclasses import dataclass, field
|
|
12
12
|
from typing import Any, Literal
|
|
13
13
|
|
|
14
|
-
from ._derived_channel import DerivedTransaction, serve_derived
|
|
14
|
+
from ._derived_channel import DerivedTransaction, serve_derived, serve_derived_replay
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
@dataclass(frozen=True, slots=True)
|
|
@@ -102,12 +102,32 @@ class SourceCapability(Source):
|
|
|
102
102
|
_inspect: Callable[[Sequence[str], Sequence[str]], SourceInspection] = field(
|
|
103
103
|
repr=False, compare=False
|
|
104
104
|
)
|
|
105
|
+
_close: Callable[[], None] | None = field(default=None, repr=False, compare=False)
|
|
105
106
|
|
|
106
107
|
def inspect(
|
|
107
108
|
self, *, components: Sequence[str] = (), configs: Sequence[str] = ()
|
|
108
109
|
) -> SourceInspection:
|
|
109
110
|
return self._inspect(tuple(components), tuple(configs))
|
|
110
111
|
|
|
112
|
+
@classmethod
|
|
113
|
+
def from_fd(cls, manifest: str, length: int, fd: int) -> SourceCapability:
|
|
114
|
+
"""Own a preconnected inspector for one exact already-admitted source."""
|
|
115
|
+
from ._source_channel import SourceClient
|
|
116
|
+
|
|
117
|
+
client = SourceClient(fd, Source(manifest, length))
|
|
118
|
+
return cls(manifest, length, client.inspect, client.close)
|
|
119
|
+
|
|
120
|
+
def close(self) -> None:
|
|
121
|
+
if self._close is not None:
|
|
122
|
+
self._close()
|
|
123
|
+
|
|
124
|
+
def __enter__(self) -> SourceCapability:
|
|
125
|
+
return self
|
|
126
|
+
|
|
127
|
+
def __exit__(self, *exc: object) -> Literal[False]:
|
|
128
|
+
self.close()
|
|
129
|
+
return False
|
|
130
|
+
|
|
111
131
|
|
|
112
132
|
@dataclass(frozen=True, slots=True)
|
|
113
133
|
class Derivation:
|
|
@@ -191,6 +211,9 @@ def derive(output: OutputCapability, declaration: Derivation) -> DerivedTransact
|
|
|
191
211
|
return output.open(declaration)
|
|
192
212
|
|
|
193
213
|
|
|
214
|
+
from ._source_channel import serve_source # noqa: E402
|
|
215
|
+
|
|
216
|
+
|
|
194
217
|
__all__ = [
|
|
195
218
|
"Source",
|
|
196
219
|
"PartSource",
|
|
@@ -205,4 +228,6 @@ __all__ = [
|
|
|
205
228
|
"DerivedTransaction",
|
|
206
229
|
"derive",
|
|
207
230
|
"serve_derived",
|
|
231
|
+
"serve_derived_replay",
|
|
232
|
+
"serve_source",
|
|
208
233
|
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/examples/optional-cache-backfill.md
RENAMED
|
File without changes
|
|
File without changes
|
{tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/examples/resident_conversion_profile.rs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/fixtures/repo_apply/blobs.jsonl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/fixtures/repo_apply/header.cbor
RENAMED
|
File without changes
|
{tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/fixtures/repo_apply/manifest.json
RENAMED
|
File without changes
|
{tensorfs-0.3.40 → tensorfs-0.3.41}/crates/tensorfs-core/tests/fixtures/repo_apply/mutation.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|