Skip to content

Commit

Permalink
feat(core): 新增一个一主双备缓存工具
Browse files Browse the repository at this point in the history
  • Loading branch information
medz committed Aug 24, 2018
1 parent 8e3677d commit c6a03ca
Showing 1 changed file with 98 additions and 0 deletions.
98 changes: 98 additions & 0 deletions app/Cache/DoubleBackup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

declare(strict_types=1);

namespace Zhiyi\Plus\Cache;

use Closure;
use Zhiyi\Plus\Support\Setting;
use Illuminate\Contracts\Cache\Factory as CacheInterface;

class DoubleBackup
{
/**
* Cache manager.
* @var \Illuminate\Contracts\Cache\Factory
*/
protected $cache;

/**
* Setting util.
* @var \Zhiyi\Plus\Support\Setting
*/
protected $setting;

/**
* Create a double backup cacher.
* @param \Illuminate\Contracts\Cache\Factory $cache
*/
public function __construct(CacheInterface $cache)
{
$this->cache = $cache;
$this->setting = $this->createSetting();
}

/**
* Get cache.
* @param string $index
* @param int $minutes
* @param \Closure $task
* @return mixed
*/
public function get(string $index, int $minutes, Closure $task)
{
$mainIndex = $index.'/main';
$backupIndexes = [
$index.'/backup-0',
$index.'/backup-1',
];

if ($this->cache->has($mainIndex)) {
return $this->randomRead(array_merge($backupIndexes, [$mainIndex]), function (array $indexes) {
return $this->randomRead($indexes);
});
} elseif ($this->setting->get($taskKey = 'cache://tasks/'.$index)) {
return null;
}

$this->setting->set($taskKey, true);
$this->cache->put($mainIndex, $contents = $task(), $expiresAt = now()->addMinutes($minutes));
foreach ($backupIndexes as $key => $value) {
$temExpiresAt = $expiresAt->addMinutes(
$minutes / ($key + 1) / 2
);
$this->cache->put($value, $contents, $temExpiresAt);
}

return $contents;
}

/**
* Create a setting util.
* @return \Zhiyi\Plus\Support\Setting
*/
public function createSetting(): Setting
{
return Setting::create('cache://double-backup');
}

/**
* Random read cache.
* @param array $indexes
* @param \Closure $next
* @return mixed
*/
protected function randomRead(array $indexes, Closure $next)
{
$indexKey = rand(0, count($indexes) - 1);
$index = $indexes[$indexKey];

if ($this->cache->has($index)) {
return $this->cache->get($index);
}

unset($indexes[$indexKey]);

return $next(array_values($indexes));
}
}

0 comments on commit c6a03ca

Please sign in to comment.