针对日志并发问题,在自动存点中增加Redis分布式冷却锁,杜绝进程重复触发导致经验暴涨,完善单元测试
This commit is contained in:
@@ -155,4 +155,36 @@ class AutoSaveExpCommandTest extends TestCase
|
||||
$user->refresh();
|
||||
$this->assertEquals(15, $user->exp_num);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试自动存点命令会通过 Redis 冷却锁,防止在短时间内并发重复调度执行。
|
||||
*/
|
||||
public function test_auto_save_cooldown_prevents_overlapping_process(): void
|
||||
{
|
||||
Sysparam::updateOrCreate(['alias' => 'exp_per_heartbeat'], ['body' => '5']);
|
||||
Cache::flush();
|
||||
|
||||
$room = Room::create(['room_name' => 'cd']);
|
||||
$user = User::factory()->create([
|
||||
'username' => 'cooldown-user',
|
||||
'exp_num' => 10,
|
||||
]);
|
||||
|
||||
Redis::hset("room:{$room->id}:users", $user->username, json_encode(['username' => $user->username], JSON_UNESCAPED_UNICODE));
|
||||
Redis::setex("room:{$room->id}:alive:{$user->username}", 90, 1);
|
||||
|
||||
// 第一次执行自动存点
|
||||
$this->artisan('chatroom:auto-save-exp')->assertSuccessful();
|
||||
|
||||
// 验证第一次加了经验 (10 + 5 = 15)
|
||||
$user->refresh();
|
||||
$this->assertEquals(15, $user->exp_num);
|
||||
|
||||
// 紧接着在冷却时间内(200秒内)模拟第二次并发执行
|
||||
$this->artisan('chatroom:auto-save-exp')->assertSuccessful();
|
||||
|
||||
// 验证因为有 Redis 冷却锁,第二次执行被拦截,经验仍为 15,并未再次增加
|
||||
$user->refresh();
|
||||
$this->assertEquals(15, $user->exp_num);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user