Publish desktop generation before its MTP reference
This commit is contained in:
parent
908c38546c
commit
d87d7cd302
2 changed files with 70 additions and 8 deletions
|
|
@ -73,6 +73,47 @@ class SyncErrorClassificationTest(unittest.TestCase):
|
|||
)
|
||||
self.assertEqual(observed, ["request-v1.json"])
|
||||
|
||||
def test_desktop_generation_directory_precedes_reference(self):
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory)
|
||||
generation = (
|
||||
"desktop-objects/generations/"
|
||||
"gen_11111111-1111-4111-8111-111111111111"
|
||||
)
|
||||
(root / generation).mkdir(parents=True)
|
||||
(root / generation / "manifest.json").write_text("manifest")
|
||||
for name in (
|
||||
"request-v1.json",
|
||||
"desktop-archive-acknowledgements-v1.json",
|
||||
"desktop-consumption-ack-v1.json",
|
||||
"desktop-generation-v1.json",
|
||||
):
|
||||
(root / name).write_text("{}")
|
||||
observed = []
|
||||
|
||||
def inspect(_adapter, _operation, _peer, outbox, _deadline):
|
||||
observed.append(
|
||||
sorted(
|
||||
str(path.relative_to(outbox))
|
||||
for path in outbox.rglob("*")
|
||||
if path.is_file()
|
||||
)
|
||||
)
|
||||
return True
|
||||
|
||||
with mock.patch.object(sync_peer_worker, "run_adapter", side_effect=inspect):
|
||||
sync_peer_worker.push_desktop_generation(
|
||||
Path("adapter"),
|
||||
"peer",
|
||||
root,
|
||||
generation,
|
||||
sync_peer_worker.time.monotonic() + 60,
|
||||
)
|
||||
self.assertEqual(len(observed), 2)
|
||||
self.assertEqual(observed[0], [generation + "/manifest.json"])
|
||||
self.assertNotIn("desktop-generation-v1.json", observed[0])
|
||||
self.assertIn("desktop-generation-v1.json", observed[1])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
|
|
@ -145,6 +145,29 @@ def push_adapter(
|
|||
run_adapter(adapter, "push", peer, outbox, deadline)
|
||||
|
||||
|
||||
def push_desktop_generation(
|
||||
adapter: Path,
|
||||
peer: str,
|
||||
root: Path,
|
||||
relative_path: str,
|
||||
deadline: float,
|
||||
) -> None:
|
||||
"""Commit immutable bytes before making their correlated reference visible."""
|
||||
push_adapter(adapter, peer, root, [relative_path], deadline)
|
||||
push_adapter(
|
||||
adapter,
|
||||
peer,
|
||||
root,
|
||||
[
|
||||
"request-v1.json",
|
||||
"desktop-archive-acknowledgements-v1.json",
|
||||
"desktop-consumption-ack-v1.json",
|
||||
"desktop-generation-v1.json",
|
||||
],
|
||||
deadline,
|
||||
)
|
||||
|
||||
|
||||
def wait_file(path: Path, deadline: float, pump=None) -> None:
|
||||
while not path.is_file():
|
||||
if time.monotonic() >= deadline:
|
||||
|
|
@ -331,17 +354,15 @@ def main() -> int:
|
|||
}
|
||||
publish_json(args.transport_root / "desktop-generation-v1.json", ref)
|
||||
if args.mode == "mtp":
|
||||
push_adapter(
|
||||
# CONTRACT: the immutable generation must be fully visible before its
|
||||
# mutable run-correlated reference. Publishing both in one MTP walk
|
||||
# lets Android observe the reference while artifacts are still being
|
||||
# transferred, turning a complete generation into a false rejection.
|
||||
push_desktop_generation(
|
||||
args.mtp_adapter,
|
||||
args.expected_peer,
|
||||
args.transport_root,
|
||||
[
|
||||
"request-v1.json",
|
||||
"desktop-archive-acknowledgements-v1.json",
|
||||
"desktop-consumption-ack-v1.json",
|
||||
"desktop-generation-v1.json",
|
||||
ref["relative_path"],
|
||||
],
|
||||
ref["relative_path"],
|
||||
deadline,
|
||||
)
|
||||
emit(
|
||||
|
|
|
|||
Loading…
Reference in a new issue