Commit Graph
40 Commits
Author SHA1 Message Date
LeoVasanko 7b1c6f6772 Fix preview pool permanently wedging after worker stderr pipe fills
Production symptom: previews of all types (pdf/pyvips/onlyoffice) start
hitting the 10s timeout and never recover until server restart, while the
rest of the server stays healthy.

Root cause (reproduced on Python 3.12): workers were spawned with
stderr=PIPE that nothing drained after startup. Once the OS pipe buffer
filled from accumulated worker tracebacks and library warnings, asyncio
flow control stopped the parent reading it and the worker blocked forever
mid-request on a stderr write. The 10s timeout then fired, but
_replace_worker hung forever in proc.wait() even after kill() — the
flow-control-paused pipe transport never sees EOF — permanently wedging
one dispatcher per stuck worker. Once all dispatchers were stuck, every
preview request timed out. Restart cleared it.

Fixes:
- Spawn workers with inherited stderr (stderr=None) so worker diagnostics
  go straight to the server log and no undrained pipe can exist.
- Bound proc.wait() in worker kill() with a 5s grace timeout so a wedged
  transport can never hang a dispatcher; log the worker pid instead.
- Guard the dispatch loop with an outer exception handler so a dispatcher
  can never die silently and shrink pool capacity.
- Retry failed worker replacement spawns with 1s-30s backoff instead of
  silently shrinking the pool.
- Fix latent crash: except-tuple referenced msgspec.json.DecodeError,
  which does not exist in the installed msgspec; any protocol failure
  would itself raise AttributeError. Use msgspec.DecodeError.
- Worker: redirect Python-level sys.stdout to stderr in persistent mode
  and keep the raw buffer solely for the binary protocol, so a library
  print() can never corrupt the command channel again (cf. the pymupdf
  deprecation warning that crashed workers at startup).
- Worker: close the pymupdf document explicitly in process_pdf.
- Log worker pid on timeout/protocol/checksum failures, and log failed
  kills and replacement retries, for future production diagnostics.

Add tests/test_preview_pool.py with an end-to-end regression recreating
the wedged-worker setup (piped, undrained stderr) plus kill-grace,
respawn-retry and dispatcher-survival tests.
2026-08-11 04:57:20 +00:00
LeoVasanko 5df2308bdb Silence CPY copyright rule; make format_access_log tail args keyword-only
Newer ruff flagged CPY001 across the codebase (copyright notices are not
wanted here, rule disabled) and PLR0917 on format_access_log. duration_ms
and extra are now keyword-only at the single call site.
2026-07-28 02:37:12 +00:00
LeoVasanko 5c4965a86b Skip removal of PLR2004. 2026-05-02 05:33:32 +00:00
LeoVasanko bd7291e9ef Lint: unused arguments 2026-05-02 05:26:47 +00:00
LeoVasanko 2fa52229cc Exception nazi and other suppression removals. Added tests on auth flows that were simplified to linter requirements. 2026-05-02 05:22:56 +00:00
LeoVasanko 2dea459d8f Update fastapi-vue-setup 1.3.1 to avoid ruff errors. Fixed devserver script on platforms where Sanic needs AppServer. 2026-05-02 05:03:43 +00:00
LeoVasanko 922069c603 Imports to top of file (ruff rule now). Refactor a couple of import cycles by implementing clear hierarchy of modules. 2026-05-02 04:46:34 +00:00
LeoVasanko 1bec73f4cd onlyoffice previews much faster and more robust, added --oosetup helper, improved error/log handling 2026-05-02 03:10:17 +00:00
LeoVasanko 8c93a4f2b5 Add OnlyOffice-based preview for office documents
Replace Aspose.Words with OnlyOffice Document Server for generating
bitmap previews of office documents (Word, Excel, PowerPoint, etc.).

Backend:
- Add cista/onlyoffice.py conversion client
- Convert office docs directly to PNG via OnlyOffice, then AVIF via pyvips
- Make office previews optional based on OnlyOffice availability
- Remove Aspose.Words dependency and all related code
- Add spreadsheet and presentation format support

Frontend:
- Mark office files as previewable in Document.ts
- Add office extensions to MediaPreview.vue preview list
- Fix pre-existing @ts-ignore in HeaderMain.vue

Tests:
- Fix test_lrucache.py parameter name (open -> opener)

Also run ruff format across the codebase to satisfy linter checks.
2026-04-26 06:59:01 +00:00
LeoVasanko eb5ff82de6 frontend: add biome checks and pre-commit integration (excluding preview files) 2026-04-26 06:43:06 +00:00
LeoVasanko f8b2c9494a WebDAV sync support, access tokens, REST control endpoints (#10)
Implement complete WebDAV file serving compatible with various clients from Windows File Explorer to more specialized sync tools. The old control WebSocket has been updated to part-DAV, part REST API instead. Implemented user:pass BASIC auth. Added UI and backend for creating tokens that avoid the need to use actual username and password for requests from CLI or DAV.
2026-04-26 04:22:52 +00:00
LeoVasanko d31ad0b525 Avoid showing previews while file upload is in progress or the file is incomplete. This avoids 500 errors on server trying to generate the preview. 2026-04-23 19:34:16 +00:00
LeoVasanko ded7ce65bc Faster image previews by pyvips. 2026-04-23 17:19:24 +00:00
LeoVasanko 134b216f4c Cleanup 2026-02-10 23:52:07 +00:00
LeoVasanko 06759b3c12 pytest deps, remove unused test group. 2026-02-10 23:46:44 +00:00
LeoVasanko 9e07a3f40d Require new fastapi-vue for unix socket compatibility. 2026-02-01 07:10:21 +00:00
LeoVasanko e7ebad3c36 Upgrade to docopt-ng because docopt is no longer maintained. 2026-01-31 22:06:03 +00:00
LeoVasanko 849b1a6868 Update scripts with latest fastapi-vue-setup. 2026-01-30 18:40:26 +00:00
LeoVasanko 7be02e951d Consistent dialog styling widgets and using Paskia's shared backdrop. Internal password auth mimics Paskia. API paths changed (/auth goes to internal or paskia depending on config). All API calls and previews get access checks. 2026-01-30 18:28:05 +00:00
LeoVasanko ba6380e71e Add a script to run devserver. Migrate to build and JS utils provided by fastapi-vue. Frontend directory renamed to frontend-build. Update Sanic, deprecations. 2026-01-21 23:32:04 +00:00
LeoVasanko 7e4c5bc911 Use zstd rather than brotli for static file compression. 2025-08-18 04:51:46 +00:00
LeoVasanko 5a5b47346f Cleanup for release 1.0.0. 2025-08-15 23:11:57 +00:00
LeoVasanko 64de17a74b Maintenance update (#7)
- Use modern tooling uv and bun
- Various changes to work with latest PyAV and PIL that have changed their API
- Improved image, video and document previews (uses AVIF, renders AVIF/HEIC/videos in HDR, faster processing)
- Fix a server hang in some cases where a folder was moved or renamed
- Log exceptions instead of only returning 500 response to client
- Log timing of preview generation functions
- Default to quality 50 in previews (previously 40)
2025-08-15 16:03:04 +00:00
LeoVasanko 211da1cdda Correct hatch build hook 2023-11-21 20:11:37 +00:00
LeoVasanko 83bc1bea81 Various build fixes, cleanup and details (#6)
- Major memory usage reduction in video previews
- Finally builds properly on Windows too
2023-11-21 15:32:49 +00:00
LeoVasanko d939c1ddbb Video preview posters 2023-11-19 08:44:46 +00:00
LeoVasanko fee66ce7ed Add pymupdf/fitz dependency 2023-11-19 07:21:11 +00:00
LeoVasanko 09e35acf87 Add PIL dependency 2023-11-19 03:40:34 +00:00
LeoVasanko c578f84753 Add frontend build to Python packaging. Remove dead code, cleanup. 2023-11-14 08:19:33 +00:00
LeoVasanko 4c9d802b65 Add project URL 2023-11-14 06:59:22 +00:00
LeoVasanko 9762d7c1ad Linting, removed extra line from pyproject.toml. 2023-11-09 05:08:46 +00:00
LeoVasanko bc67ef5fd1 Frontend created and rewritten a few times, with some backend fixes (#1)
The software is fully operational.
2023-11-08 20:38:40 +00:00
LeoVasanko b5a1fe6c4d Cleanup, bugfixes. Added access control on files and API. 2023-10-22 22:51:39 +00:00
LeoVasanko ce0b6c9bd2 Frontend included in repository. 2023-10-21 16:30:47 +00:00
LeoVasanko 447081e5d0 Implemented control commands and tests. Rewritten error and session/flash handling. 2023-10-20 22:44:43 +00:00
LeoVasanko 01028b0165 Watcher rewritten with inotify module, bugs fixed. 2023-10-19 17:52:37 +00:00
LeoVasanko d269442d7f Refactor with its own entry point and startup script cista, instead of running via sanic. Config file handling and Droppy updates. HTTP redirection/acme server added. 2023-10-18 20:06:14 +00:00
LeoVasanko 9f889232f3 Implemented login page and new jwt-based sessions. Watching cleanup. 2023-10-17 19:06:27 +00:00
LeoVasanko f6bbd7b5ff Major upgrades, much code and docs rewritten. 2023-10-17 15:33:31 +00:00
LeoVasanko 0134bd1262 Update packaging. 2023-10-15 05:00:29 +00:00