<?php
namespace JLaso\ToolsLib;
/**
* Both main classes must extends from this one, in order to have in one place all the stuff related with
* the status control file
*/
abstract class CommonAbstract
{
const STATUS_FILE = "status.pid";
/** @var string */
protected $dataFolder;
/** @var bool */
protected $debug;
/** @var string */
protected $file;
/** @var string */
protected $task;
/** @var string */
protected $oldFile;
protected $handle = null;
const DONT_UNLOCK = true;
/**
* CommonAbstract constructor.
* @param string $task
* @param bool $debug
* @internal param string $dataFolder
*/
public function __construct($task, $debug = false)
{
$this->task = $task;
$this->dataFolder = dirname(dirname(__FILE__)).'/data';
$this->debug = $debug;
if (!file_exists($this->dataFolder)) {
mkdir ($this->dataFolder, 0777);
}
$this->file = $this->dataFolder.'/'.$task.'-'.self::STATUS_FILE;
$this->oldFile = $this->dataFolder.'/'.$task.'-'.self::STATUS_FILE.'.old';
}
/**
* @return string
*/
public function getStatusFile()
{
return $this->file;
}
/**
* @return bool
*/
public function existsStatusFile()
{
return file_exists($this->file);
}
/**
* the mechanism of control of the task process is the status file, to notice to subsequents calls that
* the process is started already have to create this file, and on it is written the status of the
* different tasks
*/
public function touchStatusFile()
{
if (file_exists($this->oldFile)){
rename($this->oldFile, $this->file);
}else {
touch($this->file);
}
chmod($this->file, 0777);
}
/**
* get (in raw) the content of the status file
*
* @return string
*/
public function getStatusFileContent($dontUnlock = false)
{
if ($this->handle == null){
$this->lockStatusFile(true);
}
$content = fread($this->handle, filesize($this->file));
if (!$dontUnlock){
$this->unlockStatusFile();
}
return $content;
}
public function lockStatusFile($read = true)
{
$this->handle = fopen($this->file, "r+");
while (!flock($this->handle, LOCK_EX | LOCK_NB)){ usleep(rand($read ? 100 : 1000,$read ? 500 :1500)); }
}
public function unlockStatusFile()
{
flock($this->handle, LOCK_UN);
fclose($this->handle);
$this->handle = null;
}
/**
* saves into the status file the content passed
*
* @param string $content
*/
public function putStatusFileContent($content)
{
if ($this->handle == null){
$this->lockStatusFile();
}
ftruncate ($this->handle, 0);
fwrite($this->handle, $content);
fflush($this->handle);
usleep(1000);
$this->unlockStatusFile();
}
/**
* when the main process finish have to call this method in order to allow subsequents calls,
* be in mind that the status file is the mechanism that allow this system to know if the task
* large process is still running or not
*/
public function freeStatusFile()
{
unlink($this->file);
}
/**
* In the even the main process hangs it must call this in order to allow next process calls.
*/
public function hangOn()
{
if ($this->existsStatusFile()) {
@unlink($this->oldFile);
rename($this->file, $this->oldFile);
chmod($this->file, 0777);
}
}
}
|