mirror of
https://gitee.com/hyperf/hyperf.git
synced 2024-11-29 18:27:44 +08:00
Optimized code for deleting model cache when model deleted or saved in transaction. (#2438)
This commit is contained in:
parent
30218c6275
commit
e06423f853
@ -12,6 +12,7 @@
|
||||
## Optimized
|
||||
|
||||
- [#2429](https://github.com/hyperf/hyperf/pull/2429) Optimized error message when does not set the value of `@var` for `@Inject`.
|
||||
- [#2438](https://github.com/hyperf/hyperf/pull/2438) Optimized code for deleting model cache when model deleted or saved in transaction.
|
||||
|
||||
# v2.0.9 - 2020-08-31
|
||||
|
||||
|
@ -11,6 +11,7 @@ declare(strict_types=1);
|
||||
*/
|
||||
namespace Hyperf\ModelCache;
|
||||
|
||||
use Hyperf\ModelCache\Listener\DeleteCacheInTransactionListener;
|
||||
use Hyperf\ModelCache\Listener\DeleteCacheListener;
|
||||
|
||||
class ConfigProvider
|
||||
@ -20,6 +21,7 @@ class ConfigProvider
|
||||
return [
|
||||
'listeners' => [
|
||||
DeleteCacheListener::class,
|
||||
DeleteCacheInTransactionListener::class,
|
||||
],
|
||||
'annotations' => [
|
||||
'scan' => [
|
||||
|
36
src/model-cache/src/InvalidCacheManager.php
Normal file
36
src/model-cache/src/InvalidCacheManager.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\ModelCache;
|
||||
|
||||
use Hyperf\Utils\Traits\StaticInstance;
|
||||
|
||||
class InvalidCacheManager
|
||||
{
|
||||
use StaticInstance;
|
||||
|
||||
/**
|
||||
* @var CacheableInterface[]
|
||||
*/
|
||||
protected $models;
|
||||
|
||||
public function push(CacheableInterface $model): void
|
||||
{
|
||||
$this->models[] = $model;
|
||||
}
|
||||
|
||||
public function delete(): void
|
||||
{
|
||||
foreach ($this->models as $model) {
|
||||
$model->deleteCache();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\ModelCache\Listener;
|
||||
|
||||
use Hyperf\Database\Events\TransactionCommitted;
|
||||
use Hyperf\Event\Contract\ListenerInterface;
|
||||
use Hyperf\ModelCache\InvalidCacheManager;
|
||||
|
||||
class DeleteCacheInTransactionListener implements ListenerInterface
|
||||
{
|
||||
public function listen(): array
|
||||
{
|
||||
return [
|
||||
TransactionCommitted::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function process(object $event)
|
||||
{
|
||||
if (! $event instanceof TransactionCommitted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($event->connection->transactionLevel() === 0) {
|
||||
InvalidCacheManager::instance()->delete();
|
||||
}
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@ use Hyperf\Database\Model\Events\Event;
|
||||
use Hyperf\Database\Model\Events\Saved;
|
||||
use Hyperf\Event\Contract\ListenerInterface;
|
||||
use Hyperf\ModelCache\CacheableInterface;
|
||||
use Hyperf\ModelCache\InvalidCacheManager;
|
||||
|
||||
class DeleteCacheListener implements ListenerInterface
|
||||
{
|
||||
@ -29,11 +30,20 @@ class DeleteCacheListener implements ListenerInterface
|
||||
|
||||
public function process(object $event)
|
||||
{
|
||||
if ($event instanceof Event) {
|
||||
$model = $event->getModel();
|
||||
if ($model instanceof CacheableInterface) {
|
||||
$model->deleteCache();
|
||||
}
|
||||
if (! $event instanceof Event) {
|
||||
return;
|
||||
}
|
||||
|
||||
$model = $event->getModel();
|
||||
if (! $model instanceof CacheableInterface) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($model->getConnection()->transactionLevel() > 0) {
|
||||
InvalidCacheManager::instance()->push($model);
|
||||
return;
|
||||
}
|
||||
|
||||
$model->deleteCache();
|
||||
}
|
||||
}
|
||||
|
@ -332,4 +332,40 @@ class ModelCacheTest extends TestCase
|
||||
|
||||
$this->assertArrayHasKey('gender', $model->toArray());
|
||||
}
|
||||
|
||||
public function testModelSave()
|
||||
{
|
||||
$container = ContainerStub::mockContainer();
|
||||
/** @var \Redis $redis */
|
||||
$redis = $container->make(RedisProxy::class, ['pool' => 'default']);
|
||||
|
||||
$id = 208;
|
||||
UserModel::query()->firstOrCreate(['id' => $id], [
|
||||
'name' => uniqid(),
|
||||
'gender' => 1,
|
||||
]);
|
||||
|
||||
$model = UserModel::findFromCache($id);
|
||||
$name = uniqid();
|
||||
$model->name = $name;
|
||||
$model->save();
|
||||
|
||||
$this->assertSame(0, $redis->exists('{mc:default:m:user}:id:' . $id));
|
||||
|
||||
$model = UserModel::findFromCache($id);
|
||||
$this->assertSame($name, $model->name);
|
||||
$connection = $model->getConnection();
|
||||
$connection->transaction(function () use ($id, $redis) {
|
||||
$model = UserModel::findFromCache($id);
|
||||
$name = uniqid();
|
||||
$model->name = $name;
|
||||
$model->save();
|
||||
UserModel::findFromCache($id);
|
||||
$this->assertSame(1, $redis->exists('{mc:default:m:user}:id:' . $id));
|
||||
});
|
||||
|
||||
$this->assertSame(0, $redis->exists('{mc:default:m:user}:id:' . $id));
|
||||
|
||||
$model->delete();
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,9 @@ use Hyperf\Contract\StdoutLoggerInterface;
|
||||
use Hyperf\Database\ConnectionResolverInterface;
|
||||
use Hyperf\Database\Connectors\ConnectionFactory;
|
||||
use Hyperf\Database\Connectors\MySqlConnector;
|
||||
use Hyperf\Database\Events\TransactionCommitted;
|
||||
use Hyperf\Database\Model\Events\Deleted;
|
||||
use Hyperf\Database\Model\Events\Saved;
|
||||
use Hyperf\DbConnection\Collector\TableCollector;
|
||||
use Hyperf\DbConnection\ConnectionResolver;
|
||||
use Hyperf\DbConnection\Frequency;
|
||||
@ -29,6 +32,8 @@ use Hyperf\Framework\Logger\StdoutLogger;
|
||||
use Hyperf\ModelCache\EagerLoad\EagerLoader;
|
||||
use Hyperf\ModelCache\Handler\RedisHandler;
|
||||
use Hyperf\ModelCache\Handler\RedisStringHandler;
|
||||
use Hyperf\ModelCache\Listener\DeleteCacheInTransactionListener;
|
||||
use Hyperf\ModelCache\Listener\DeleteCacheListener;
|
||||
use Hyperf\ModelCache\Manager;
|
||||
use Hyperf\ModelCache\Redis\LuaManager;
|
||||
use Hyperf\Pool\Channel;
|
||||
@ -59,7 +64,6 @@ class ContainerStub
|
||||
'log_level' => [
|
||||
LogLevel::ALERT,
|
||||
LogLevel::CRITICAL,
|
||||
LogLevel::DEBUG,
|
||||
LogLevel::EMERGENCY,
|
||||
LogLevel::ERROR,
|
||||
LogLevel::INFO,
|
||||
@ -122,7 +126,12 @@ class ContainerStub
|
||||
$connectionFactory = new ConnectionFactory($container);
|
||||
$container->shouldReceive('get')->with(ConnectionFactory::class)->andReturn($connectionFactory);
|
||||
|
||||
$eventDispatcher = new EventDispatcher(new ListenerProvider(), $logger);
|
||||
$provider = new ListenerProvider();
|
||||
$listener = new DeleteCacheListener();
|
||||
$provider->on(TransactionCommitted::class, [new DeleteCacheInTransactionListener(), 'process']);
|
||||
$provider->on(Saved::class, [$listener, 'process']);
|
||||
$provider->on(Deleted::class, [$listener, 'process']);
|
||||
$eventDispatcher = new EventDispatcher($provider, $logger);
|
||||
$container->shouldReceive('get')->with(EventDispatcherInterface::class)->andReturn($eventDispatcher);
|
||||
|
||||
$container->shouldReceive('get')->with('db.connector.mysql')->andReturn(new MySqlConnector());
|
||||
|
Loading…
Reference in New Issue
Block a user