In the previous parts of this article we have seen how to use MongoDB to acquire a lock for a program which must run as a single instance at any time on your servers.

However, long-lived locks are sometimes dangerous for two forces that counteract each other:

- to avoid the lock expiring before the program finishes to execute, you must find an upper bound for the execution time of your program and set the lock duration as a longer period.

- To avoid leaving a periodical program inactive for a long time, you must try to keep the lock as short as possible so that if a process crashes or terminates abruptly a substitute can start again, as soon as the lock expires.

To bypass this trade-off, you can acquire a short-lived lock called a *lease* and periodically renew it throughout the program execution. The pattern to follow is:

<?php
$lock->acquire();
foreach ($thingsToDo as $thing) {
    $thing();
    $lock->renew();
}
$lock->release();

Here is the code for the renew() method:

<?php
$programName = "my_report_generation";
$processName = gethostname() . ":" . getmypid();
$now = new DateTime();
$expiration = (new DateTime())->add(new DateInterval("PT10M"));
$collection = (new MongoClient())->test->locks;

$result = $collection->update(
    [
        "program" => $programName,
        "process" => $processName,
    ],
    [
        "$set" => [
            "expires_at" => new MongoDate($expiration->getTimestamp()),
        ]
    ]
);
if ($result["n"] != 1) {
    throw new RuntimeException("Cannot renew the lock for $programName!");
}
echo "Lock renewed!", PHP_EOL;

We make a conditional update on the lock document by checking our program and process name are present in it. We check that exactly 1 (not 0) documents were updated by this operation and if this is true we declare the lock successfully renewed and we continue execution.

Distributed locks with MongoDB: releasing (part 2)

Distributed locks with MongoDB: acquiring (part 1)

Giorgio Sironi

Developer at Onebip , Website , Git home page , @giorgiosironi , Linkedin profile
I search for the harmony between form and context, which is a fancy way of saying I build software to fit in the world I'm in and its rapid changes. In the specific, my areas of expertise are testing, OOP design and distributed computing.

All articles by Giorgio Sironi

Comments

comments powered by Disqus

cloudparty

Follow Us