mojolicious / minion

:octopus: Perl high performance job queue

Home Page:https://metacpan.org/release/Minion

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Feature Request] Finalizier task for locks

simcop2387 opened this issue · comments

Right now you can achieve this by having a task that waits on the lock to be released and does a ->retry() if it's still present. This mostly works but has a few problems. If something unlocks the lock before the task checking it is run, then it's open to be re-locked. This means that you have no reliable way to do an action (such as deleting a file, or changing something in another database, sending an email or alert, etc.) when the lock is released. Most of this can of course be worked around by being defensive around what uses the lock but it would be much more ergonomic to be able to automatically trigger a job when the lock is released.

My thought is something along the lines of (I know it's not all that idiomatic looking),

$minion->lock(foobar => 3600, {limit => 1, finalize => [lock_removed => [additional, args, here]});

$minion->add_task(lock_removed => sub {
   my ($job, $lock, @additional_args) = @_;

   if ($lock->is_expired()) {
      # remove file here
      # also send alert that this lock expired
   } elsif ($lock->unlocked()) {
      # remove file here
   } else {
       # not sure what else could happen here
   }
});

The finalizer would not be allowed to prevent the lock from being removed, and shouldn't be allowed to re-lock it either (as it would still exist while it's running).

I also understand that at least the expiration part would be very very difficult to actually implement (who would be responsible for watching for the expiration?) and it might have to be run effectively like a job being ->foreground()ed to not cause deadlocks or other problems when unlocking a lock.

My main use-case for coming to this is thinking about temp files and using a lock for reference counting on them and removing them when the is fully released. But I can also see an expiring lock sending out some kind of alert being useful since it could indicate something has gone wrong with whatever used that lock.

I think you'd also have to restrict the finalizer's ability to have some parameters attached to them (such as parent jobs, attempts, and things like that) but i think if the immediately obvious problems with the idea can be solved then it would end up rather powerful.