mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
fix: add X-Tigris-Consistent headers to all rclone commands (#558)
Signed-off-by: phernandez <paul@basicmachines.co> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -27,6 +27,14 @@ console = Console()
|
||||
# Minimum rclone version for --create-empty-src-dirs support
|
||||
MIN_RCLONE_VERSION_EMPTY_DIRS = (1, 64, 0)
|
||||
|
||||
# Tigris edge caching returns stale data for users outside the origin region (iad).
|
||||
# These headers bypass edge cache and force reads/writes against the origin.
|
||||
# See: https://www.tigrisdata.com/docs/objects/consistency/
|
||||
TIGRIS_CONSISTENCY_HEADERS = [
|
||||
"--header-download", "X-Tigris-Consistent: true",
|
||||
"--header-upload", "X-Tigris-Consistent: true",
|
||||
]
|
||||
|
||||
|
||||
class RunResult(Protocol):
|
||||
returncode: int
|
||||
@@ -210,6 +218,7 @@ def project_sync(
|
||||
"sync",
|
||||
str(local_path),
|
||||
remote_path,
|
||||
*TIGRIS_CONSISTENCY_HEADERS,
|
||||
"--filter-from",
|
||||
str(filter_path),
|
||||
]
|
||||
@@ -279,6 +288,7 @@ def project_bisync(
|
||||
"bisync",
|
||||
str(local_path),
|
||||
remote_path,
|
||||
*TIGRIS_CONSISTENCY_HEADERS,
|
||||
"--resilient",
|
||||
"--conflict-resolve=newer",
|
||||
"--max-delete=25",
|
||||
@@ -354,6 +364,7 @@ def project_check(
|
||||
"check",
|
||||
str(local_path),
|
||||
remote_path,
|
||||
*TIGRIS_CONSISTENCY_HEADERS,
|
||||
"--filter-from",
|
||||
str(filter_path),
|
||||
]
|
||||
@@ -393,6 +404,6 @@ def project_ls(
|
||||
if path:
|
||||
remote_path = f"{remote_path}/{path}"
|
||||
|
||||
cmd = ["rclone", "ls", remote_path]
|
||||
cmd = ["rclone", "ls", *TIGRIS_CONSISTENCY_HEADERS, remote_path]
|
||||
result = run(cmd, capture_output=True, text=True, check=True)
|
||||
return result.stdout.splitlines()
|
||||
|
||||
@@ -8,6 +8,7 @@ import pytest
|
||||
|
||||
from basic_memory.cli.commands.cloud.rclone_commands import (
|
||||
MIN_RCLONE_VERSION_EMPTY_DIRS,
|
||||
TIGRIS_CONSISTENCY_HEADERS,
|
||||
RcloneError,
|
||||
SyncProject,
|
||||
bisync_initialized,
|
||||
@@ -40,6 +41,18 @@ class _Runner:
|
||||
return _RunResult(returncode=self._returncode, stdout=self._stdout)
|
||||
|
||||
|
||||
def _assert_has_consistency_headers(cmd: list[str]) -> None:
|
||||
"""Assert the rclone command includes Tigris consistency headers."""
|
||||
assert "--header-download" in cmd
|
||||
assert "X-Tigris-Consistent: true" in cmd
|
||||
assert "--header-upload" in cmd
|
||||
# Verify upload header value follows --header-upload
|
||||
upload_idx = cmd.index("--header-upload")
|
||||
assert cmd[upload_idx + 1] == "X-Tigris-Consistent: true"
|
||||
download_idx = cmd.index("--header-download")
|
||||
assert cmd[download_idx + 1] == "X-Tigris-Consistent: true"
|
||||
|
||||
|
||||
def _write_filter_file(tmp_path: Path) -> Path:
|
||||
p = tmp_path / "filters.txt"
|
||||
p.write_text("- .git/**\n", encoding="utf-8")
|
||||
@@ -127,6 +140,7 @@ def test_project_sync_success(tmp_path):
|
||||
assert cmd[:2] == ["rclone", "sync"]
|
||||
assert Path(cmd[2]) == Path("/tmp/research")
|
||||
assert cmd[3] == "basic-memory-cloud:my-bucket/research"
|
||||
_assert_has_consistency_headers(cmd)
|
||||
assert "--filter-from" in cmd
|
||||
assert str(filter_path) in cmd
|
||||
assert "--dry-run" in cmd
|
||||
@@ -208,6 +222,7 @@ def test_project_bisync_success(tmp_path):
|
||||
assert result is True
|
||||
cmd, _ = runner.calls[0]
|
||||
assert cmd[:2] == ["rclone", "bisync"]
|
||||
_assert_has_consistency_headers(cmd)
|
||||
assert "--resilient" in cmd
|
||||
assert "--conflict-resolve=newer" in cmd
|
||||
assert "--max-delete=25" in cmd
|
||||
@@ -369,6 +384,7 @@ def test_project_check_success(tmp_path):
|
||||
assert result is True
|
||||
cmd, kwargs = runner.calls[0]
|
||||
assert cmd[:2] == ["rclone", "check"]
|
||||
_assert_has_consistency_headers(cmd)
|
||||
assert kwargs["capture_output"] is True
|
||||
assert kwargs["text"] is True
|
||||
|
||||
@@ -407,6 +423,8 @@ def test_project_ls_success():
|
||||
project = SyncProject(name="research", path="app/data/research")
|
||||
files = project_ls(project, "my-bucket", run=runner, is_installed=lambda: True)
|
||||
assert files == ["file1.md", "file2.md", "subdir/file3.md"]
|
||||
cmd, _ = runner.calls[0]
|
||||
_assert_has_consistency_headers(cmd)
|
||||
|
||||
|
||||
def test_project_ls_with_subpath():
|
||||
|
||||
Reference in New Issue
Block a user