Skip to content

Commit

Permalink
support different cache strategy
Browse files Browse the repository at this point in the history
always enable runtime cache
  • Loading branch information
git committed Aug 15, 2018
1 parent 9acf12e commit bd08e9b
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 89 deletions.
200 changes: 118 additions & 82 deletions src/Setting.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,126 @@
*/
class Setting
{
private $cacheEnabled = false;

private $cachePrefix = '';
const CACHE_BATCH = 'batch';
const CACHE_SINGLE = 'single';

private $cacheTTL = 60;

private $runtimeCacheEnabled = true;
protected $cacheEnabled = false;
/**
* Cache Key prefix
*
* @var string
*/
protected $cachePrefix = '';
/**
* Cache TTL (minutes)
*
* @var int
*/
protected $cacheTTL = 60;
/**
* Store setiings during life time
*
* @var array
*/
protected $runtimeCache = [];

private $runtimeCache = [];
protected $cacheMode = 'single';

protected $batchCacheKey = 'batch';

function __construct()
{
$this->cacheMode = config('lara-setting.cache.mode', 'single');
$this->cacheEnabled = config('lara-setting.cache.enable') ? true : false;
$this->cachePrefix = config('lara-setting.cache.prefix');
$this->cacheTTL = config('lara-setting.cache.ttl', 60);
//Only in BATCH mode ,should load all of the config from cache to runtime
$this->loadToRunTIme();
}

protected function getCache($key, $default = null)
{
if ($this->cacheEnabled) {
return Cache::get($key, $default);
}
return null;
}

protected function setCache($key, $value)
{
if ($this->cacheEnabled) {
return Cache::set($key, $value, $this->cacheTTL);
}
return false;
}

protected function forgetCache($key)
{
if ($this->cacheEnabled) {
return Cache::forget($key);
}
return false;
}

$this->runtimeCacheEnabled = config('lara-setting.runtime') ? true : false;
/**
* Load all of the records from cache to runtime;
* for bacth mode
*/
protected function loadToRunTime()
{
if ($this->cacheMode == self::CACHE_BATCH) {
$cache = $this->getCache($this->batchKey());
if (empty($cache)) {
//no records in Cache ,load all from db
$this->loadFromDB();
} else {
$this->runtimeCache = $cache;
}
}
}

protected function batchKey()
{
return $this->cachePrefix . $this->batchCacheKey;
}

/**
* Get all or single records from db
*
* @param $group
* @param $key
* @return string|array
*/
protected function loadFromDB($group = null, $key = null)
{
$builder = Settings::query()->select(['group', 'key', 'value']);
if (!empty($group) && !empty($key)) {
$builder->where(compact('group', 'key'));
}
$records = $builder->get();
/** @var Settings $record */
foreach ($records as $record) {
$gr = $record->getAttribute('group');
$ke = $record->getAttribute('key');
$val = $record->getAttribute('value');
//save to cache in SINGLE mode
if ($this->cacheMode == self::CACHE_SINGLE) {
$cacheKey = $this->cacheKey($gr, $ke);
$this->setCache($cacheKey, $val);
}
//save to runtime
$this->runtimeCache[$gr][$ke] = $val;
}
if ($this->cacheMode == self::CACHE_BATCH) {
Cache::set($this->batchKey(), $this->runtimeCache, $this->cacheTTL);
}

if (!empty($group) && !empty($key)) {
return array_get($this->runtimeCache, $group . '.' . $key);
}
return $this->runtimeCache;
}

/**
* Get setting from cache or db by full key
Expand All @@ -46,56 +145,20 @@ public function get($key, $update = false)
try {
list($group, $k) = $this->prepareKey($key);

//try to get from the runtime cache
if ($update) {
//Load from db and update cache
return $this->loadFromDB($group, $k);
return $need = $this->loadFromDB($group, $k);
} else {
if ($this->runtimeCacheEnabled && isset($this->runtimeCache[$group][$k])) {
return $this->runtimeCache[$group][$k];
}

$cacheKey = $this->cacheKey($group, $k);
$need = array_get($this->runtimeCache, $key, null);
if (!is_null($need)) return $need;
//load from framework's cache
$value = Cache::get($cacheKey, null);

if (is_null($value)) {
return $this->loadFromDB($group, $k);
}
if ($this->runtimeCacheEnabled) {
$this->runtimeCache[$group][$k] = $value;
if ($this->cacheEnabled) {
$cacheKey = $this->cacheKey($group, $k);
$need = $this->getCache($cacheKey, null);
if (!is_null($need)) return $need;
}
return $value;
}
} catch (\Exception $exception) {
return null;
}
}


public function loadFromDB($group, $key)
{
try {
$model = Settings::where(compact('group', 'key'))->first();
// get the value save to cache
if (empty($model)) throw new \Exception();
$value = $model->getAttributeValue('value');

//can not cache null value it will load from db every time
if (is_null($value)) return null;

if ($this->cacheEnabled) {
$cacheKey = $this->cacheKey($group, $key);
Cache::put($cacheKey, $value, $this->cacheTTL);
}

if ($this->runtimeCacheEnabled) {
$this->runtimeCache[$group][$key] = $value;
return $this->loadFromDB($group, $k);
}

return $value;
} catch (\Exception $exception) {
//record do not exist or ..
return null;
}
}
Expand All @@ -110,26 +173,20 @@ public function loadFromDB($group, $key)
public function set($key, $value)
{
try {

list($group, $k) = $this->prepareKey($key);

$model = Settings::query()->firstOrNew(['group' => $group, 'key' => $k]);
$model->setAttribute('value', $value);
$model->save();

//update runtime cache
if ($this->runtimeCacheEnabled) $this->runtimeCache[$group][$k] = $value;

$this->runtimeCache[$group][$k] = $value;
//update framework's cache
if ($this->cacheEnabled) Cache::put($this->cacheKey($group, $k), $value, $this->cacheTTL);

$this->setCache($this->cacheKey($group, $k), $value);
return true;

} catch (\Exception $exception) {
return false;
}
}


/**
* Remove one setting from db and cache
Expand All @@ -141,14 +198,10 @@ public function forget($fKey)
{
try {
list($group, $key) = $this->prepareKey($fKey);

$model = Settings::query()->where(compact('group', 'key'))->firstOrFail();

$model->delete();

unset($this->runtimeCache[$group][$key]);
Cache::forget($this->cacheKey($group, $key));

$this->forgetCache($this->cacheKey($group, $key));
return true;
} catch (\Exception $exception) {
return false;
Expand All @@ -171,23 +224,6 @@ private function prepareKey($key)
return [$group, $k];
}

public function clearRuntimeCache()
{
$this->runtimeCache = [];
}

public function enableRuntimeCache()
{
$this->runtimeCacheEnabled = true;
}

public function disableRuntimeCache()
{
$this->runtimeCacheEnabled = false;
$this->clearRuntimeCache();
}


private function cacheKey($group, $key)
{
return $this->cachePrefix . ':' . $group . ':' . $key;
Expand Down
19 changes: 12 additions & 7 deletions src/lara-setting.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,24 @@
*/

return [

//use framework's cache drive
/*
|--------------------------------------------------------------------------
| Cache settings
|--------------------------------------------------------------------------
| Cache use framework's cache drive.
| Supported cache mode : 'single', 'batch'
| single : get/update/cache settings records one by one
| batch : cache all of the setting records together
|
*/
'cache' => [

'mode' => 'batch',
'enable' => true,
'prefix' => 'settings_',
'prefix' => 'settings:',
//cache time .minutes
'ttl' => 60,
],

//Runtime cache
'runtime' => true,

//Facade name LaraSetting::get(..)
'facade' => 'LaraSetting',
];

0 comments on commit bd08e9b

Please sign in to comment.