feat: refresh VFS
This commit is contained in:
@@ -44,3 +44,10 @@ RUSTFS_VERSION_BUCKET=versions
|
||||
RUSTFS_RUN_LOG_BUCKET=run-logs
|
||||
RUSTFS_TRASH_BUCKET=trash
|
||||
RUSTFS_TRASH_RETENTION_DAYS=30
|
||||
|
||||
# rclone RC (HTTP control API). The runtime container starts rclone with
|
||||
# `--rc --rc-addr 0.0.0.0:5572 --rc-no-auth` (see runtime/src/runtime/mount.py),
|
||||
# so the backend can POST /vfs/refresh here to invalidate the FUSE dir-cache
|
||||
# after writing new workspace files. Default points at the runtime service
|
||||
# over the compose network.
|
||||
RCLONE_RC_URL=http://runtime:5572
|
||||
|
||||
@@ -16,6 +16,7 @@ from backend.auth import router as auth_router
|
||||
from backend.jupyter import router as jupyter_router
|
||||
from backend.resources import router as resources_router
|
||||
from backend.runtime_client import RuntimeClient
|
||||
from backend.rclone_rc_client import RcloneRCClient
|
||||
from backend.schedule_runs import router as schedule_runs_router
|
||||
from backend.schedules import router as schedules_router
|
||||
from backend.scripts import router as scripts_router
|
||||
@@ -59,9 +60,16 @@ async def lifespan(app: Any) -> AsyncIterator[None]:
|
||||
timeout=httpx.Timeout(30.0),
|
||||
)
|
||||
app.state.runtime_client = RuntimeClient(runtime_http_client)
|
||||
# Short timeout — refresh is best-effort and runs in a BackgroundTask.
|
||||
rclone_http_client = httpx.AsyncClient(
|
||||
base_url=settings.rclone_rc_url,
|
||||
timeout=httpx.Timeout(30.0),
|
||||
)
|
||||
app.state.rclone_rc_client = RcloneRCClient(rclone_http_client)
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
await rclone_http_client.aclose()
|
||||
await runtime_http_client.aclose()
|
||||
await storage_http_client.aclose()
|
||||
await engine.dispose()
|
||||
|
||||
@@ -10,6 +10,7 @@ from typing import Any
|
||||
|
||||
from fastapi import (
|
||||
APIRouter,
|
||||
BackgroundTasks,
|
||||
Depends,
|
||||
Header,
|
||||
HTTPException,
|
||||
@@ -344,6 +345,7 @@ async def create_script_record(
|
||||
async def create_script(
|
||||
payload: CreateScriptRequest,
|
||||
request: Request,
|
||||
background_tasks: BackgroundTasks,
|
||||
context: RequestContext = Depends(request_context),
|
||||
session: AsyncSession = Depends(database_session),
|
||||
) -> dict[str, Any]:
|
||||
@@ -359,6 +361,11 @@ async def create_script(
|
||||
context=context,
|
||||
session=session,
|
||||
)
|
||||
background_tasks.add_task(
|
||||
request.app.state.rclone_rc_client.vfs_refresh,
|
||||
dir_path=context.workspace.workspace_id,
|
||||
recursive=True,
|
||||
)
|
||||
return {
|
||||
"request_id": context.request_id,
|
||||
"data": script_payload(script, storage_data),
|
||||
@@ -372,6 +379,7 @@ async def create_script(
|
||||
)
|
||||
async def upload_script(
|
||||
request: Request,
|
||||
background_tasks: BackgroundTasks,
|
||||
file_name: str = Query(min_length=1, max_length=255),
|
||||
parent_path: str = Query(default="", max_length=1024),
|
||||
visibility: str = Query(
|
||||
@@ -413,6 +421,11 @@ async def upload_script(
|
||||
context=context,
|
||||
session=session,
|
||||
)
|
||||
background_tasks.add_task(
|
||||
request.app.state.rclone_rc_client.vfs_refresh,
|
||||
dir_path=context.workspace.workspace_id,
|
||||
recursive=True,
|
||||
)
|
||||
return {
|
||||
"request_id": context.request_id,
|
||||
"data": script_payload(script, storage_data),
|
||||
|
||||
@@ -54,6 +54,10 @@ class Settings(BaseSettings):
|
||||
default="http://runtime:8000",
|
||||
description="Backend → Runtime HTTP endpoint.",
|
||||
)
|
||||
rclone_rc_url: str = Field(
|
||||
default="http://runtime:5572",
|
||||
description="Backend → rclone RC HTTP endpoint (VFS cache invalidation).",
|
||||
)
|
||||
|
||||
# ── RustFS object storage ────────────────────────────────────
|
||||
rustfs_endpoint: str = Field(
|
||||
|
||||
Reference in New Issue
Block a user