我试图将用户活动保存在一个json文件中,但当文件大小变大,多个用户同时工作时,json文件会删除旧记录。
这是我的特质
trait CustomLogActivity
{
protected static function bootCustomLogActivity()
{
foreach (static::getModelEvents() as $event) {
static::$event(function ($model) use ($event) {
$model->recordActivity($event);
});
}
}
protected static function getModelEvents()
{
return ['created', 'updated', 'deleted'];
}
protected function recordActivity($event)
{
$activity = [
'user_id' => Auth::id(),
'type' => $event,
'subject' => (new \ReflectionClass($this))->getShortName(),
'timestamp' => now()
];
if ($event === 'updated') {
$activity['old_properties'] = $this->getOriginal();
$activity['new_properties'] = $this->getAttributes();
} else {
$activity['properties'] = $this->getAttributes();
}
$this->appendToLog($activity);
}
protected function appendToLog($activity)
{
$logFile = 'activity.json';
$log = json_encode($activity);
Storage::append($logFile, $log);
}
protected function getActivityType($event)
{
$type = strtolower((new \ReflectionClass($this))->getShortName());
return "{$event}_{$type}";
}
}
1条答案
按热度按时间u3r8eeie1#
正如我在一些评论中提到的,我会把它作为一个答案发布,所以它是解释任何人有这些类型的问题:
您遇到的错误称为:concurrency.
我假设2个进程同时使用该文件,因此两者都读取当前内容,但其中一个在写入后,另一个进程在内存中已经有数据(因此该进程无法获取新数据),但没有新内容,因此它将覆盖该文件...
首先,使用一个队列(事件)发送数据,然后使用Redis,或者数据库或者其他对此超级快的东西,但不是字面上的文件,你可以瞬间丢失它,但不是数据库...
您仍然可以使用文件,但我不建议这样做,因为它在很大程度上取决于您的基础设施:
所以我所要做的就是有一个队列(通过使用事件触发),让这个队列用一个工作者来处理这个超级特定的任务。但是你必须考虑到速度,如果你在队列中得到的事件比一个工作者所能解决的要多,你必须找到一个解决方案