Skip to content

Commit

Permalink
Fix to named runs feature in Library that protects against concurrent…
Browse files Browse the repository at this point in the history
… appends to the cached named run file.
  • Loading branch information
KrisJordan committed May 4, 2009
1 parent 343b20c commit cb565a3
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 19 deletions.
33 changes: 23 additions & 10 deletions recess/recess/cache/Cache.class.php
Expand Up @@ -233,17 +233,30 @@ class SqliteCacheProvider implements ICacheProvider {
function __construct() {
$this->pdo = new Pdo('sqlite:' . $_ENV['dir.temp'] . 'sqlite-cache.db');
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
$this->setStatement = $this->pdo->prepare('INSERT OR REPLACE INTO cache (key,value,expire) values (:key,:value,:expire)');
$this->getStatement = $this->pdo->prepare('SELECT value,expire FROM cache WHERE key = :key');
$this->getManyStatement = $this->pdo->prepare('SELECT value,expire,key FROM cache WHERE key LIKE :key');
} catch(PDOException $e) {
$this->pdo->exec('CREATE TABLE "cache" ("key" TEXT PRIMARY KEY NOT NULL , "value" TEXT NOT NULL , "expire" INTEGER NOT NULL)');
$this->pdo->exec('CREATE INDEX "expiration" ON "cache" ("expire" ASC)');
$this->setStatement = $this->pdo->prepare('INSERT OR REPLACE INTO cache (key,value,expire) values (:key,:value,:expire)');
$this->getStatement = $this->pdo->prepare('SELECT value,expire FROM cache WHERE key = :key');
$this->getManyStatement = $this->pdo->prepare('SELECT value,expire,key FROM cache WHERE key LIKE :key');

$tries = 0;
while($tries < 2) {
try {
$this->setStatement = $this->pdo->prepare('INSERT OR REPLACE INTO cache (key,value,expire) values (:key,:value,:expire)');
$this->getStatement = $this->pdo->prepare('SELECT value,expire FROM cache WHERE key = :key');
$this->getManyStatement = $this->pdo->prepare('SELECT value,expire,key FROM cache WHERE key LIKE :key');
break;
} catch(PDOException $e) {

try {
$this->pdo->exec('CREATE TABLE "cache" ("key" TEXT PRIMARY KEY NOT NULL , "value" TEXT NOT NULL , "expire" INTEGER NOT NULL)');
$this->pdo->exec('CREATE INDEX "expiration" ON "cache" ("expire" ASC)');
} catch(PDOException $e) {
if($tries == 1) {
die('Could not create cache table');
}
sleep(1);
$tries++;
continue;
}
}
}

$this->time = time();
}

Expand Down
3 changes: 1 addition & 2 deletions recess/recess/framework/Application.class.php
@@ -1,7 +1,6 @@
<?php
Library::import('recess.framework.controllers.Controller');
Library::import('recess.framework.views.SmartyView');
Library::import('recess.framework.views.NativeView');
Library::import('recess.framework.views.RecessView');
Library::import('recess.database.orm.Model');

abstract class Application {
Expand Down
1 change: 1 addition & 0 deletions recess/recess/lang/ClassDescriptor.class.php
@@ -1,5 +1,6 @@
<?php
Library::import('recess.lang.AttachedMethod');
Library::import('recess.lang.WrappedMethod');

/**
* Recess PHP Framework class info object that stores additional
Expand Down
32 changes: 25 additions & 7 deletions recess/recess/lang/Library.class.php
Expand Up @@ -44,6 +44,7 @@ class Library {
static private $namedRun;
static private $namedRuns = array();
static private $inNamedRunImport = false;
static private $namedRunFileSize = 0;

static function beginNamedRun($name) {
if(!self::$useNamedRuns || !isset($_ENV['dir.temp'])) return;
Expand All @@ -60,7 +61,8 @@ static function beginNamedRun($name) {
$namedRunFile = $_ENV['dir.temp'] . self::NAMED_RUNS_PATH . $name . self::PHP_EXTENSION;
if(file_exists($namedRunFile)) {
self::$inNamedRunImport = true;
include_once($namedRunFile);
include($namedRunFile);
self::$namedRunFileSize = filesize($namedRunFile);
self::$inNamedRunImport = false;
}
}
Expand All @@ -70,23 +72,35 @@ static function namedRunMissed($class) {
self::$namedRuns[self::$namedRun][] = $class;
}

static function persistNamedRuns() {
static function persistNamedRuns() {
if(!isset($_ENV['dir.temp'])) return;
$tempDir = $_ENV['dir.temp'];
foreach(self::$namedRuns as $namedRun => $missedClasses) {
$namedRunDir = $_ENV['dir.temp'] . self::NAMED_RUNS_PATH;
$namedRunFile = $namedRunDir . $namedRun . self::PHP_EXTENSION;

if(!empty($missedClasses)) {
if(file_exists($namedRunFile)) { // append to
$file = fopen($namedRunFile,'a');
$tempNamedRunFile = '';
$tries = 0;
do {
$tempNamedRunFile = $namedRunFile . '.' . rand(0,32768);
} while(file_exists($tempNamedRunFile));

if(file_exists($namedRunFile)) {
copy($namedRunFile, $tempNamedRunFile);
$file = fopen($tempNamedRunFile,'a');
if(filesize($tempNamedRunFile) !== self::$namedRunFileSize) {
fclose($file);
unlink($tempNamedRunFile);
return;
}
} else {
if(!file_exists($namedRunDir)) {
mkdir($namedRunDir);
mkdir($tempNamedRunFile);
}
$file = fopen($namedRunFile,'w');
$file = fopen($tempNamedRunFile,'w');
}

foreach($missedClasses as $class) {
$classInfo = self::$classesByClass[$class];
$fullName = $classInfo[self::NAME];
Expand All @@ -99,6 +113,10 @@ static function persistNamedRuns() {
}

fclose($file);

copy($tempNamedRunFile, $namedRunFile);

unlink($tempNamedRunFile);
}
}
}
Expand Down

0 comments on commit cb565a3

Please sign in to comment.