Follow-up of #5953.
Refactor the concerns with two goals:
- Getting closer from the way ActiveStorage adds its own hooks.
Usually ActiveStorage does this using an `Attachment#after_create`
hook, which then delegates to the blob to enqueue the job.
- Enqueuing each job only once. By hooking on `Attachment#after_create`,
we guarantee each job will be added only once.
We then let the jobs themselves check if they are relevant or not, and
retry or discard themselves if necessary.
We also need to update the tests a bit, because Rails'
`perform_enqueued_jobs(&block)` test helper doesn't honor the `retry_on`
clause of jobs. Instead it forwards the exception to the caller – which
makes the test fail.
Instead we use the inline version of `perform_enqueued_jobs()`, without
a block, which properly ignores errors catched by retry_on.
As the comment states, it would be nice to load the Virus Scanner on
the Attachment (rather than the blob).
However, in order not to clobber the blob metadata, we want to run the
VirusScanner once the blob analyzer did run.
And the most direct way to detect that the blob analyzer did run is to
add an `on_update_commit` hook on the blob, as this hook will be
trigerred when saving changes to the metadata. This is what the current
solution uses.
So the current solution is almost optimal, and has a low chance of
accidentally clobbering the blob metadata – as the virus scanner is only
started when the analysis phase is finished.
We are making these changes in order to always use DS_Proxy. Before this change DS_Proxy was not used to write files when ActiveStorage was used directly and not through “direct upload”.