Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#12: Add expiration time for memcache lock storage #13

Merged
merged 32 commits into from
Jun 13, 2015

Conversation

arvenil
Copy link
Owner

@arvenil arvenil commented Jun 12, 2015

TLDR

->setExpiration($expirationInSeconds)

<?php
require 'vendor/autoload.php';

use NinjaMutex\Lock\MemcacheLock;
use NinjaMutex\Mutex;

$memcache = new Memcache();
$memcache->connect('127.0.0.1', 11211);
$lock = new MemcacheLock($memcache);
$lock->setExpiration(1800) // 1800s = 30 minutes
$mutex = new Mutex('very-critical-stuff', $lock);
if ($mutex->acquireLock(1000)) {
    // Do some very critical stuff

    // and release lock after you finish
    $mutex->releaseLock();
} else {
    throw new Exception('Unable to gain lock!');
}

Explanation

If you gain lock with Memcache or Memcached and the program crashes it may lead to situation where the lock is not released as it is not automatically released when program dies (in theory there is __destruct that should release the lock but this may not always work). Flock and MySQL implementation doesn't have this drawback as the lock is released when file handle is released (flock) or connection is closed (MySQL) and those both things happen when php script dies.

To bypass the issue for Memcache and Memcached you can now use ->setExpiration($expirationInSeconds) method to allow lock to expire.

Be aware this method is highly unrecommended as it may lead to race conditions if lock expires and it was still actually held by still working process. This is for users who knows what they do ;) I would suggest high values for ->setExpiration($expiration) and adding logging to your script if locking took more time than $expiration so you know the $expiration time was set too low.

If script which gained the lock is still running while the lock expires then when it will try to release the lock it will fail or throw UnrecoverableMutexException in __destructor (or if lock was gained by another script already - race condition - then the second one may fail this way). In other words if any of your scripts fails with this exception or while executing ->releaseLock() then a) you screwed up with setting ->setExpiration() :) b) Memcache or Memcached became unavailable service (#2).

Why so huge PR?

Numerous problems and bugs encountered while trying to write tests for this (some of the issues)

arvenil added a commit that referenced this pull request Jun 13, 2015
#12: Add expiration time for memcache lock storage
@arvenil arvenil merged commit 6bc68b4 into master Jun 13, 2015
@arvenil arvenil deleted the issue12_add_expire_for_memcache branch June 13, 2015 19:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant