Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat:多站点策略缓存问题:使用数据库连接和表名作为缓存KEY #46

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions config/tauthz.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,21 @@
// 策略表完整名称.
'rules_table' => null,
],

/** 缓存配置 */
'cache' => [
// changes whether Lauthz will cache the rules.
'enabled' => false,

// cache store
'store' => 'default',

// cache Key
'key' => 'rules',

// 缓存有效期 0表示永久缓存
'expire' => 0,
],
],
],
];
59 changes: 47 additions & 12 deletions src/adapter/DatabaseAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
use Casbin\Persist\FilteredAdapter;
use Casbin\Persist\Adapters\Filter;
use Casbin\Exceptions\InvalidFilterTypeException;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
use Throwable;

/**
* DatabaseAdapter.
Expand Down Expand Up @@ -78,17 +82,28 @@ public function savePolicyLine($ptype, array $rule)
foreach ($rule as $key => $value) {
$col['v'.strval($key).''] = $value;
}
$this->model->cache('tauthz')->insert($col);
if($this->model->cacheEnabled){
$_cacheKey = $this->model->getConnection().':'.$this->model->cacheKey;
$this->model = $this->model->cache($_cacheKey,$this->model->cacheExpire);
}
$this->model->insert($col);
}

/**
* loads all policy rules from the storage.
*
* @param Model $model
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function loadPolicy(Model $model): void
{
$rows = $this->model->cache('tauthz')->field(['ptype', 'v0', 'v1', 'v2', 'v3', 'v4', 'v5'])->select()->toArray();
if($this->model->cacheEnabled){
$_cacheKey = $this->model->getConnection().':'.$this->model->cacheKey;
$this->model = $this->model->cache($_cacheKey,$this->model->cacheExpire);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

关于缓存的key还是建议直接读取配置,不需要拼接connection,默认这个属性也是空的
多站点配置不同缓存key就行了,更灵活。不必和connection绑死

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

默认的connection 不是空的呀!就是当前数据库连接名称。我这边有200多个站点配置不同key也不现实呀

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

实际业务场景就是需要要拼接connection 。应为是Saas部署,每个Saas都有不同数据库

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getConnection() 取的是配置文件中的连接标识,并不是数据库连接地址、库名称之类的,你可以试下,默认空,执行的才会取default的配置。
不会配200个连接标识,配置的是env的连接地址等。
之所以推荐走模型事件,就是解耦,缓存也更灵活。

}
$rows = $this->model->field(['ptype', 'v0', 'v1', 'v2', 'v3', 'v4', 'v5'])->select()->toArray();
foreach ($rows as $row) {
$this->loadPolicyArray($this->filterRule($row), $model);
}
Expand Down Expand Up @@ -148,28 +163,38 @@ public function addPolicies(string $sec, string $ptype, array $rules): void
$cols[$i++] = $temp;
$temp = [];
}
$this->model->cache('tauthz')->insertAll($cols);
if($this->model->cacheEnabled){
$_cacheKey = $this->model->getConnection().':'.$this->model->cacheKey;
$this->model = $this->model->cache($_cacheKey,$this->model->cacheExpire);
}
$this->model->insertAll($cols);
}

/**
* This is part of the Auto-Save feature.
*
* @param string $sec
* @param string $ptype
* @param array $rule
* @param array $rule
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function removePolicy(string $sec, string $ptype, array $rule): void
{
$count = 0;

$_cacheKey = '';
if($this->model->cacheEnabled){
$_cacheKey = $this->model->getConnection().':'.$this->model->cacheKey;
}
$instance = $this->model->where('ptype', $ptype);

foreach ($rule as $key => $value) {
$instance->where('v'.strval($key), $value);
}

foreach ($instance->select() as $model) {
if ($model->cache('tauthz')->delete()) {
if ($model->cache($_cacheKey)->delete()) {
++$count;
}
}
Expand Down Expand Up @@ -204,7 +229,6 @@ public function _removeFilteredPolicy(string $sec, string $ptype, int $fieldInde
{
$count = 0;
$removedRules = [];

$instance = $this->model->where('ptype', $ptype);
foreach (range(0, 5) as $value) {
if ($fieldIndex <= $value && $value < $fieldIndex + count($fieldValues)) {
Expand All @@ -213,12 +237,15 @@ public function _removeFilteredPolicy(string $sec, string $ptype, int $fieldInde
}
}
}

$_cacheKey = '';
if($this->model->cacheEnabled){
$_cacheKey = $this->model->getConnection().':'.$this->model->cacheKey;
}
foreach ($instance->select() as $model) {
$item = $model->hidden(['id', 'ptype'])->toArray();
$item = $this->filterRule($item);
$removedRules[] = $item;
if ($model->cache('tauthz')->delete()) {
if ($model->cache($_cacheKey)->delete()) {
++$count;
}
}
Expand All @@ -230,10 +257,11 @@ public function _removeFilteredPolicy(string $sec, string $ptype, int $fieldInde
* RemoveFilteredPolicy removes policy rules that match the filter from the storage.
* This is part of the Auto-Save feature.
*
* @param string $sec
* @param string $ptype
* @param int $fieldIndex
* @param string $sec
* @param string $ptype
* @param int $fieldIndex
* @param string|null ...$fieldValues
* @throws Throwable
*/
public function removeFilteredPolicy(string $sec, string $ptype, int $fieldIndex, ?string ...$fieldValues): void
{
Expand All @@ -248,6 +276,9 @@ public function removeFilteredPolicy(string $sec, string $ptype, int $fieldIndex
* @param string $ptype
* @param string[] $oldRule
* @param string[] $newPolicy
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function updatePolicy(string $sec, string $ptype, array $oldRule, array $newPolicy): void
{
Expand Down Expand Up @@ -329,6 +360,10 @@ public function setFiltered(bool $filtered): void
*
* @param Model $model
* @param mixed $filter
* @throws DataNotFoundException
* @throws DbException
* @throws InvalidFilterTypeException
* @throws ModelNotFoundException
*/
public function loadFilteredPolicy(Model $model, $filter): void
{
Expand Down
39 changes: 26 additions & 13 deletions src/model/Rule.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,52 @@ class Rule extends Model implements Arrayable
* @var array
*/
protected $schema = [
'id' => 'int',
'id' => 'int',
'ptype' => 'string',
'v0' => 'string',
'v1' => 'string',
'v2' => 'string',
'v3' => 'string',
'v4' => 'string',
'v5' => 'string',
'v0' => 'string',
'v1' => 'string',
'v2' => 'string',
'v3' => 'string',
'v4' => 'string',
'v5' => 'string',
];

/** 缓存是否开启 @var string */
protected $cacheEnabled;

/** 设置缓存key @var string */
protected $cacheKey;

/** 设置缓存key过期时间 @var int */
protected $cacheExpire;

/**
* 架构函数
* @access public
* @param array $data 数据
* @param array $data
*/
public function __construct($data = [])
public function __construct(array $data = [])
{
$this->connection = $this->config('database.connection') ?: '';
$this->table = $this->config('database.rules_table');
$this->name = $this->config('database.rules_name');

$this->cacheEnabled = $this->config('cache.enabled', false);
$this->cacheKey = $this->config('cache.key');
$this->cacheExpire = $this->config('cache.expire');
parent::__construct($data);
}

/**
* Gets config value by key.
*
* @param string $key
* @param string $default
* @param string|null $key
* @param null $default
*
* @return mixed
*/
protected function config(string $key = null, $default = null)
{
$driver = config('tauthz.default');
return config('tauthz.enforcers.'.$driver.'.'.$key, $default);
return config('tauthz.enforcers.' . $driver . '.' . $key, $default);
}
}
Loading