📎 Webclip
Background jobs with Oban, part 1: stop blocking your LiveView
This post moves slow preview fetching out of a LiveView event handler and into an Oban job. It shows how the app keeps the link creation flow responsive by inserting a job after the link is saved, then letting a worker fetch the page, store the metadata, and mark the link ready or failed.
Reading notes#
- Oban stores jobs in the database, so if PostgreSQL is already in use there is no separate queue server to deploy.
- The example app, Unfurl, pastes in a URL, fetches page data, stores title, description, and preview image, and displays the result.
- The current implementation fetches preview data inside the LiveView
savehandler, so a slow site blocks the user. - The setup adds
obanandoban_web, runsmix deps.get, and creates an Oban jobs table with a migration based on Oban’s manual installation guide. - The configuration uses
Oban.Engines.Basic, points Oban atUnfurl.Repo, defines apreviewsqueue with concurrency 5, setsprunerto delete finished jobs after seven days, and setslifelineto rescue jobs after one hour. - Oban is added to the application’s supervision tree, and test configuration sets
testing: :manualso jobs are inserted but not executed automatically. - A
PreviewWorkermodule usesOban.Workerwith thepreviewsqueue and up to five attempts. - The worker receives a job with a link ID, looks up the link, fetches preview data, applies it on success, and marks the link as failed on error.
- If the link no longer exists, the worker returns
{:cancel, :link_deleted}so Oban stops retrying. - The
Linksmodule gainsfetch_link,apply_preview,mark_failed, andschedule_preview. apply_previewsetsfetched_atto the current time and stores the fetched attributes with statusready.schedule_previewbuilds a job from the link ID withPreviewWorker.newand inserts it withOban.insert.- The LiveView
savehandler now creates the link, enqueues the job, and shows a flash message instead of fetching immediately. - After the change, the page stays responsive, and the preview appears after refresh once the background work finishes.
