Skip to content

Commit

Permalink
added locking
Browse files Browse the repository at this point in the history
  • Loading branch information
hiqsol committed Apr 24, 2016
1 parent 2cdf655 commit 9f38225
Showing 1 changed file with 87 additions and 11 deletions.
98 changes: 87 additions & 11 deletions src/models/Storage.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

namespace hiqdev\assetpackagist\models;

use Exception;
use Yii;
use yii\helpers\Json;

class Storage
{
protected static $_instance;
protected static $_lockHandle;
protected static $_lockCount = 0;

protected function __construct()
{
Expand All @@ -24,7 +27,70 @@ static public function getInstance()

public function getNextID()
{
return rand(1000000, 2000000);
$this->getLock();
$nextID = $this->readLastID() + 1;
$this->writeLastID($nextID);
$this->releaseLock();

return $nextID;
}

protected function readLastId()
{
$path = $this->getLastIDPath();

return file_exists($path) ? (int)file_get_contents($path) : 1000000;
}

protected function writeLastId($value)
{
file_put_contents($this->getLastIDPath(), $value);
}

protected function getLastIDPath()
{
return Yii::getAlias('@web/lastid');
}

protected function getLockHandle()
{
if (static::$_lockHandle === null) {
$path = Yii::getAlias('@web/lock');
if (!file_exists($path)) {
file_put_contents($path, 'lock');
}
static::$_lockHandle = fopen($path, 'r+');
}

return static::$_lockHandle;
}

public function hasLock()
{
return (bool)static::$_lockCount;
}

protected function getLock()
{
if (!$this->hasLock()) {
if (!flock($this->getLockHandle(), LOCK_EX)) {
throw new Exception('failed get lock');
}
}
++$this->_lockCount;
}

protected function releaseLock()
{
if ($this->_lockCount<1) {
throw new Exception('no lock to release');
}
if ($this->_lockCount === 1) {
if (!flock($this->getLockHandle(), LOCK_UN)) {
throw new Exception('failed release lock');
}
}
--$this->_lockCount;
}

public function writePackage(AssetPackage $package)
Expand All @@ -39,10 +105,14 @@ public function writePackage(AssetPackage $package)
$hash = hash('sha256', $json);
$path = static::buildPath($name, $hash);
if (!file_exists($path)) {
static::mkdir(dirname($path));
file_put_contents($path, $json);
file_put_contents(static::buildPath($name), $json);
$this->writeProviderLatest($name, $hash);
$this->getLock();
{
static::mkdir(dirname($path));
file_put_contents($path, $json);
file_put_contents(static::buildPath($name), $json);
$this->writeProviderLatest($name, $hash);
}
$this->releaseLock();
}

return $hash;
Expand Down Expand Up @@ -85,10 +155,13 @@ protected function writeProviderLatest($name, $hash)
$hash = hash('sha256', $json);
$path = Yii::getAlias("@web/p/provider-latest$$hash.json");
if (!file_exists($path)) {
file_put_contents($path, $json);
/// TODO lock
file_put_contents($latest_path, Json::encode($data));
$this->writePackagesJson($hash);
$this->getLock();
{
file_put_contents($path, $json);
file_put_contents($latest_path, Json::encode($data));
$this->writePackagesJson($hash);
}
$this->releaseLock();
}

return $hash;
Expand All @@ -105,8 +178,11 @@ protected function writePackagesJson($hash)
],
],
];
/// TODO lock
file_put_contents(Yii::getAlias('@web/packages.json'), Json::encode($data));
$this->getLock();
{
file_put_contents(Yii::getAlias('@web/packages.json'), Json::encode($data));
}
$this->releaseLock();
}

public static function mkdir($dir)
Expand Down

0 comments on commit 9f38225

Please sign in to comment.