This repository has been archived by the owner on Oct 8, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 85cce7d
Showing
6 changed files
with
194 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
version: 2.0 | ||
jobs: | ||
build: | ||
environment: | ||
CC_TEST_REPORTER_ID: b0e2dc22a6c4744ffb6a4a8597af2062cce268cbfd8c9baaaa660d79ed33a803 | ||
docker: | ||
- image: circleci/php:7-cli-node-browsers-legacy | ||
working_directory: ~/repo | ||
steps: | ||
- checkout | ||
- run: | ||
name: Setup dependencies | ||
command: | | ||
sudo composer self-update | ||
composer install -n --prefer-dist | ||
- run: | ||
name: Setup Code Climate test-reporter | ||
command: | | ||
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter | ||
chmod +x ./cc-test-reporter | ||
- run: | ||
name: Run tests | ||
command: | | ||
./cc-test-reporter before-build | ||
vendor/bin/phpunit --testsuite all --coverage-clover clover.xml | ||
./cc-test-reporter after-build --coverage-input-type clover --exit-code $? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Locker | ||
![CircleCI (all branches)](https://img.shields.io/circleci/project/github/fmizzell/datastore.svg) | ||
[![Maintainability](https://api.codeclimate.com/v1/badges/c04818119efc862221cd/maintainability)](https://codeclimate.com/github/fmizzell/locker/maintainability) | ||
[![Test Coverage](https://api.codeclimate.com/v1/badges/c04818119efc862221cd/test_coverage)](https://codeclimate.com/github/fmizzell/locker/test_coverage) | ||
[![GPLv3 license](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0.en.html) | ||
|
||
A cross-process lock. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"name": "fmizzell/locker", | ||
"description": "A cross-process lock.", | ||
"license": "GPL-3.0-only", | ||
"authors": [ | ||
{ | ||
"name": "fmizzell", | ||
"email": "[email protected]" | ||
} | ||
], | ||
"autoload": { | ||
"psr-4": { | ||
"Locker\\": "src/" | ||
} | ||
}, | ||
"require-dev": { | ||
"phpunit/phpunit": "^7.4" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<phpunit | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.3/phpunit.xsd" | ||
verbose="false"> | ||
|
||
<testsuites> | ||
<testsuite name="all"> | ||
<directory suffix="Test.php" phpVersion="7.2" phpVersionOperator=">=">test</directory> | ||
</testsuite> | ||
</testsuites> | ||
|
||
<filter> | ||
<whitelist processUncoveredFilesFromWhitelist="true"> | ||
<directory suffix=".php">src</directory> | ||
</whitelist> | ||
</filter> | ||
|
||
</phpunit> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
<?php | ||
|
||
namespace Locker; | ||
|
||
|
||
class Locker | ||
{ | ||
|
||
private $timeWaited = -1; | ||
private $name; | ||
private $expire; | ||
private $wait; | ||
|
||
/** | ||
* Constructor. | ||
* | ||
* @param string $name | ||
* The locks name. | ||
* | ||
* @param int $expire | ||
* When the lock is set, it will automatically expire after | ||
* this amount of time has passed if the lock is not released. | ||
* | ||
* @param int $wait | ||
* Time we are willing to wait for the lock before we bail. | ||
*/ | ||
public function __construct($name, $expire = 30, $wait = 5) | ||
{ | ||
$this->name = $name; | ||
$this->expire = $expire; | ||
$this->wait = $wait; | ||
} | ||
|
||
/** | ||
* Wait until we get the lock, or we get tired of waiting. | ||
*/ | ||
public function getLock() { | ||
do { | ||
$this->wait(); | ||
if ($this->timeWaited > $this->wait) { | ||
$this->timeWaited = -1; | ||
throw new \Exception("The lock was not acquire after {$this->wait} second(s)."); | ||
} | ||
$this->lockExpired(); | ||
} while (!$this->lockCreated()); | ||
|
||
$this->timeWaited = -1; | ||
return TRUE; | ||
} | ||
|
||
/** | ||
* Release the lock. | ||
*/ | ||
public function releaseLock() { | ||
$path = "/tmp/{$this->name}.lock"; | ||
if (file_exists($path)) { | ||
array_map('unlink', glob("{$path}/*.*")); | ||
rmdir($path); | ||
} | ||
} | ||
|
||
private function wait() { | ||
if ($this->timeWaited >= 0) { | ||
sleep(1); | ||
} | ||
$this->timeWaited++; | ||
} | ||
|
||
private function lockExpired() { | ||
$file = "/tmp/{$this->name}.lock/expire.txt"; | ||
if (file_exists($file) && file_get_contents($file) < time()) { | ||
$this->releaseLock(); | ||
return TRUE; | ||
} | ||
return FALSE; | ||
} | ||
|
||
private function lockCreated() { | ||
$lock_path = "/tmp/{$this->name}.lock"; | ||
if (@mkdir($lock_path, 0700)) { | ||
file_put_contents("{$lock_path}/expire.txt", (time() + $this->expire)); | ||
return TRUE; | ||
} | ||
return FALSE; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?php | ||
|
||
|
||
class LockerTest extends \PHPUnit\Framework\TestCase | ||
{ | ||
private $locker; | ||
|
||
protected function setUp() | ||
{ | ||
$this->locker = new \Locker\Locker("test", 5, 1); | ||
} | ||
|
||
public function testReleaseAndWait() { | ||
$this->assertTrue($this->locker->getLock()); | ||
|
||
try { | ||
$this->locker->getLock(); | ||
} | ||
catch(\Exception $e) { | ||
$this->assertEquals($e->getMessage(), "The lock was not acquire after 1 second(s)."); | ||
} | ||
|
||
$this->locker->releaseLock(); | ||
$this->assertTrue($this->locker->getLock()); | ||
} | ||
|
||
public function testExpiration() { | ||
$this->assertTrue($this->locker->getLock()); | ||
sleep(6); | ||
$this->assertTrue($this->locker->getLock()); | ||
} | ||
|
||
protected function tearDown() | ||
{ | ||
$this->locker->releaseLock(); | ||
} | ||
|
||
} |