Skip to content

VerifyAttachmentHash unique lock never expires #409

Closed

Description

@amazing-cat

Summary

VerifyAttachmentHash is a ShouldBeUnique job without uniqueFor, so its unique lock never expires. If the lock is not released — or is released in a different cache than the one it was taken in — hash verification of that attachment is silently skipped from then on.

Details

  • app/Jobs/VerifyAttachmentHash.php:15 — implements ShouldQueue, ShouldBeUnique, uniqueId() = attachment id, no $uniqueFor.
  • The lock is acquired by the dispatcher (Illuminate\Bus\UniqueLock::acquire) and released by the worker after the job finishes (Illuminate\Queue\CallQueuedHandler).
  • Dispatchers: web on upload (app/Services/AttachmentService.php:141) and the scheduler daily for every attachment (app/Console/Commands/VerifyAttachments.php:37, routes/console.php:19).
  • The default cache store is file (config/cache.php:18), local to each container.

When the dispatcher and the worker don't share the cache store — separate web/queue/scheduler containers or Pods (#376), or several hosts — the worker releases a lock that doesn't exist in its cache, and the dispatcher's lock stays forever: all later dispatches for that attachment are dropped without any log entry. The same happens whenever a lock is left behind for any other reason, because nothing expires it.

Proposed fix

  • Add public int $uniqueFor = 3600; (or a bound that exceeds the expected verification time of the largest attachment) to VerifyAttachmentHash.
  • Document that a shared cache store (e.g. Redis) is required when web, queue and scheduler run in separate containers; the Helm chart rework (Rewrite Kubernetes chart for Cattr 4.1 runtime #376) configures this.
  • Other ShouldBeUnique jobs already set uniqueFor (GenerateScreenshotThumbnail 3600s, AssignAppsToTimeInterval 60s, ClearExpiredApps 3600s).

Acceptance criteria

  • A stale VerifyAttachmentHash lock expires and the attachment is verified again on the next daily run.
  • Test: dispatch while a stale lock exists → after uniqueFor the job is queued again.

Metadata

Metadata

Assignees

No one assigned

    Labels

    phpPull requests that update Php code

    Type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions