CP-13299 Fix lazy preview caching#64
Merged
Merged
Conversation
## Summary
Pages beyond `MAX_NUMBER_OF_PAGES_PROCESSED` (15) are rendered on-demand
by `PreviewDocumentPageController#show`. Before regenerating, the
controller looks for an existing cached blob:
```ruby
preview_image = attachment.preview_images.joins(:blob)
.find_by(blob: { filename: ["#{params[:id]}.png", "#{params[:id]}.jpg"] })
But Templates::ProcessDocument.generate_pdf_preview_from_file was
saving the blob as "#{page_number}.jpeg" — .jpeg ≠ .jpg, so the
cache lookup never matched. Every request to /preview/<token>/<n>.jpg
re-downloaded the source PDF, re-rendered the page through Pdfium, and
created a duplicate ActiveStorage::Attachment.
Impact in production
- Editor shows broken images for pages 16+ when Pdfium fails under
repeated load.
- Duplicate ActiveStorage::Attachment records pile up (no dedup on
create!).
- Wasted S3 upload + Pdfium CPU on every editor render of pages 16+.
Change
One-line fix: save lazy-generated previews as .jpg so the
controller's cache lookup matches and redirects to the existing blob
on subsequent requests.
Test
Added spec/lib/templates/process_document_spec.rb running the exact
controller-side find_by against a freshly generated preview. Locks
in the filename contract so a future regression to .jpeg (or any
other non-matching extension) fails immediately.
Manually verified the failure mode by reverting the fix locally — spec
fails with got: nil from the cache lookup.
Two notes if you want to tweak before pushing:
- The triple-backtick block in the description renders nicely on GitHub but you may want to drop it if your PR template is bare text.
- This fix doesn't address the other two issues we discussed (nil-blob 500s, partial-tempfile corruption). Worth a one-liner at the end of the
description like *"Follow-ups (separate tickets): nil-blob handling in controller, tempfile completeness check"* — so reviewers don't think those
are out of scope by omission.
jewls618
reviewed
May 11, 2026
| def generate_pdf_preview_from_file(attachment, file_path, page_number) | ||
| doc = Pdfium::Document.open_file(file_path) | ||
|
|
||
| blob = build_and_upload_blob(doc, page_number, '.jpeg') |
There was a problem hiding this comment.
[Non-blocking] Do we need to worry about any existing .jpeg blobs in production?
Member
Author
There was a problem hiding this comment.
Great call out, probably not since this still still in early labs, but I'll double check!
Member
Author
There was a problem hiding this comment.
No, we don't since nothing will break, we'll have a small amount of duplicate .jpeg files sitting around in prod but since the number of people using this product is so low I don't mind letting those orphaned dupe images sit in S3, the number is probably insignificant and not worth the clean-up.
Great question, and thanks for the sanity check!
jewls618
approved these changes
May 11, 2026
jewls618
left a comment
There was a problem hiding this comment.
Looks good 👍 just left one non-blocking comment/concern.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Fixes a bug in production where any page after
15was rendering intermittently.Pages beyond
MAX_NUMBER_OF_PAGES_PROCESSED(15) are rendered on-demandby
PreviewDocumentPageController#show. Before regenerating, thecontroller looks for an existing cached blob: