Improved Storage garbage collection

Improved RecRmDir() and RecTimeDirRemove()
This commit is contained in:
djmaze 2021-12-17 01:17:06 +01:00
parent 7df3ed665d
commit 5b4d34d1cb
6 changed files with 52 additions and 32 deletions

View file

@ -26,7 +26,7 @@ class DemoStorage extends \RainLoop\Providers\Storage\FileStorage
// Garbage collection
if (!static::$gc_done) {
static::$gc_done = true;
if (\is_dir($sDataPath) && 0 === \random_int(0, 100)) {
if (!\random_int(0, \max(50, \ini_get('session.gc_divisor')))) {
\MailSo\Base\Utils::RecTimeDirRemove($sDataPath, 3600 * 3); // 3 hours
}
}
@ -37,7 +37,6 @@ class DemoStorage extends \RainLoop\Providers\Storage\FileStorage
} else if (StorageType::SESSION === $iStorageType) {
$sDataPath .= '/.sessions';
}
\is_dir($sDataPath) || \mkdir($sDataPath, 0700, true);
return $sDataPath . '/' . ($sKey ? \RainLoop\Utils::fixName($sKey) : '');
}

View file

@ -886,8 +886,8 @@ abstract class Utils
public static function RecRmDir(string $sDir) : bool
{
if (\is_dir($sDir))
{
\clearstatcache();
if (\is_dir($sDir)) {
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($sDir, \FilesystemIterator::SKIP_DOTS),
\RecursiveIteratorIterator::CHILD_FIRST);
@ -899,27 +899,34 @@ abstract class Utils
}
}
\clearstatcache();
// \realpath_cache_size() && \clearstatcache(true);
return \rmdir($sDir);
}
return false;
}
public static function RecTimeDirRemove(string $sTempPath, int $iTime2Kill, int $iNow = 0) : bool
public static function RecTimeDirRemove(string $sDir, int $iTime2Kill) : bool
{
$iTime = ($iNow ?: \time()) - $iTime2Kill;
\clearstatcache();
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($sTempPath, \FilesystemIterator::SKIP_DOTS),
\RecursiveIteratorIterator::CHILD_FIRST);
foreach ($iterator as $path) {
if ($path->isFile() && '.' !== $path->getBasename()[0] && $path->getMTime() < $iTime) {
\unlink($path);
if (\is_dir($sDir)) {
$iTime = \time() - $iTime2Kill;
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($sDir, \FilesystemIterator::SKIP_DOTS),
\RecursiveIteratorIterator::CHILD_FIRST);
foreach ($iterator as $path) {
if ($path->isFile() && $path->getMTime() < $iTime) {
\unlink($path);
} else if ($path->isDir() && !(new \FilesystemIterator($path))->valid()) {
\rmdir($path);
}
}
\clearstatcache();
// \realpath_cache_size() && \clearstatcache(true);
return !(new \FilesystemIterator($sDir))->valid() && \rmdir($sDir);
}
\clearstatcache();
return true;
return false;
}
public static function Utf8Truncate(string $sUtfString, int $iLength) : string

View file

@ -466,14 +466,14 @@ class Actions
public function StorageProvider(bool $bLocal = false): Providers\Storage
{
if ($bLocal) {
if (null === $this->oLocalStorageProvider) {
if (!$this->oLocalStorageProvider) {
$this->oLocalStorageProvider = new Providers\Storage(
$this->fabrica('storage-local'));
}
return $this->oLocalStorageProvider;
} else {
if (null === $this->oStorageProvider) {
if (!$this->oStorageProvider) {
$this->oStorageProvider = new Providers\Storage(
$this->fabrica('storage'));
}

View file

@ -253,6 +253,10 @@ trait User
$this->Logger()->Write('Cacher GC: Begin');
$this->Cacher()->GC(48);
$this->Logger()->Write('Cacher GC: End');
$this->Logger()->Write('Storage GC: Begin');
$this->StorageProvider()->GC();
$this->Logger()->Write('Storage GC: End');
}
else if ($bFilesCache)
{

View file

@ -81,12 +81,16 @@ class Storage extends \RainLoop\Providers\AbstractProvider
public function IsActive() : bool
{
return $this->oDriver instanceof \RainLoop\Providers\Storage\IStorage;
return true;
}
public function IsLocal() : bool
{
return $this->oDriver instanceof \RainLoop\Providers\Storage\IStorage &&
$this->oDriver->IsLocal();
return $this->oDriver->IsLocal();
}
public function GC() : void
{
$this->oDriver->GC();
}
}

View file

@ -24,7 +24,7 @@ class FileStorage implements \RainLoop\Providers\Storage\IStorage
public function __construct(string $sStoragePath, bool $bLocal = false)
{
$this->sDataPath = \rtrim(\trim($sStoragePath), '\\/');
$this->bLocal = !!$bLocal;
$this->bLocal = $bLocal;
$this->oLogger = null;
}
@ -34,7 +34,13 @@ class FileStorage implements \RainLoop\Providers\Storage\IStorage
public function Put($mAccount, int $iStorageType, string $sKey, string $sValue) : bool
{
$sFileName = $this->generateFileName($mAccount, $iStorageType, $sKey, true);
return $sFileName && false !== \file_put_contents($sFileName, $sValue);
try {
$sFileName && \RainLoop\Utils::saveFile($sFileName, $sValue);
return true;
} catch (\Throwable $e) {
\error_log("{$e->getMessage()}: {$sFileName}");
}
return false;
}
/**
@ -138,16 +144,6 @@ class FileStorage implements \RainLoop\Providers\Storage\IStorage
}
}
// Cleanup SignMe
if (StorageType::SIGN_ME === $iStorageType && $sKey && 0 === \random_int(0, 25) && \is_dir($sFilePath)) {
\MailSo\Base\Utils::RecTimeDirRemove(\is_dir($sFilePath), 3600 * 24 * 30); // 30 days
}
// Cleanup sessions
if (StorageType::SESSION === $iStorageType && $sKey && 0 === \random_int(0, 25) && \is_dir($sFilePath)) {
\MailSo\Base\Utils::RecTimeDirRemove(\is_dir($sFilePath), 3600 * 3); // 3 hours
}
return $sFilePath;
}
@ -155,4 +151,14 @@ class FileStorage implements \RainLoop\Providers\Storage\IStorage
{
$this->oLogger = $oLogger;
}
public function GC() : void
{
foreach (\glob("{$this->sDataPath}/*", GLOB_ONLYDIR) as $sDomain) {
foreach (\glob("{$sDomain}/*", GLOB_ONLYDIR) as $sLocal) {
\MailSo\Base\Utils::RecTimeDirRemove("{$sLocal}/.sign_me", 3600 * 24 * 30); // 30 days
\MailSo\Base\Utils::RecTimeDirRemove("{$sLocal}/.sessions", 3600 * 3); // 3 hours
}
}
}
}