Separate OnlyOffice async handling, add office_previews WS flag, framed worker protocol

- Move OnlyOffice conversion out of worker subprocesses into async event loop
  using httpx.AsyncClient with shared client and clean shutdown hook
- Add OOConversionManager with in-flight deduplication (asyncio.Future) and
  configurable concurrency limit (OO_MAX_CONCURRENT=2)
- Add 10s total timeout for office previews via asyncio.wait_for
- Return 503 when OnlyOffice is unavailable, 504 on timeout
- Remove office handling from worker dispatch(); workers now only do
  images, video, and PDFs
- Replace PNG tempfile bridge with framed binary input protocol on worker
  stdin: (json_size)(data_size)(json)(raw_data)
- Add process_image_buffer() for in-memory AVIF conversion via pyvips
- Add office_previews to WS server message, cached every 30s from OO
  availability check
- Frontend gates only office document previews on office_previews flag;
  images, video, PDFs remain unconditional
- Change default OnlyOffice port from 8080 to 8988
This commit is contained in:
Leo Vasanko
2026-05-01 03:42:03 +00:00
parent cb954db537
commit 49cb4a8255
8 changed files with 396 additions and 91 deletions
+2 -1
View File
@@ -16,7 +16,7 @@ from setproctitle import setproctitle
from stream_zip import ZIP_AUTO, stream_zip
from zstandard import ZstdCompressor
from cista import auth, config, fileserver, preview, session, sharefs, sso, watching
from cista import auth, config, fileserver, onlyoffice, preview, session, sharefs, sso, watching
from cista.api import bp
from cista.preview import shutdown_preview_workers, start_preview_workers
from cista.sanic_logging import (
@@ -130,6 +130,7 @@ async def main_start(app):
@app.before_server_stop
async def main_stop(app):
watching.stop(app)
await onlyoffice.close_oo_client()
await shutdown_preview_workers()
app.ctx.threadexec.shutdown()
app.ctx.zipexec.shutdown(cancel_futures=True)