release 1.13.4: monpages race-proof publish and content checks
Avoid false TOP/content ERRORs from mid-publish races: atomic HTML write, rsync --delay-updates + settle, monpages fetch retries with larger head windows, pre-publish soft content, bootstrap markers.
This commit is contained in:
parent
d5213adb7a
commit
e450470429
5 changed files with 179 additions and 73 deletions
|
|
@ -5,6 +5,7 @@ from __future__ import annotations
|
|||
import argparse
|
||||
import html
|
||||
import re
|
||||
import os
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
|
|
@ -27,6 +28,22 @@ def format_generated_now() -> tuple[str, str]:
|
|||
generated_at = now.strftime("%Y-%m-%d %H:%M:%S") + f" {tz_name}"
|
||||
return generated_at, generated_iso
|
||||
|
||||
|
||||
def atomic_write_text(path: Path, text: str, encoding: str = "utf-8") -> None:
|
||||
"""Write file atomically (tmp + replace) so monpages never curls a half-written page."""
|
||||
path = Path(path)
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
tmp = path.with_name(f".{path.name}.tmp.{os.getpid()}")
|
||||
try:
|
||||
tmp.write_text(text, encoding=encoding)
|
||||
os.replace(tmp, path)
|
||||
finally:
|
||||
if tmp.exists():
|
||||
try:
|
||||
tmp.unlink()
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
def ui_lang(explicit: str = "") -> str:
|
||||
"""en (default) or fr. Env: TALER_MON_LANG; auto fr for lefrancpaysan hosts."""
|
||||
import os
|
||||
|
|
@ -1901,8 +1918,7 @@ def main() -> None:
|
|||
suite_version_url=getattr(args, "suite_version_url", "") or "",
|
||||
)
|
||||
|
||||
args.out.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.out.write_text(html_out, encoding="utf-8")
|
||||
atomic_write_text(args.out, html_out, encoding="utf-8")
|
||||
print(f"wrote {args.out} (errors={n_err} warnings={n_warn} level={status_level(n_err, n_warn)})")
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue