mirror of https://github.com/MISP/MISP
Merge pull request #7174 from JakubOnderka/event-locks-faster
chg: [internal] Faster event locks with Redispull/7182/head
commit
e46745c0b9
|
@ -5374,7 +5374,7 @@ class EventsController extends AppController
|
||||||
throw new MethodNotAllowedException('This endpoint requires a POST request.');
|
throw new MethodNotAllowedException('This endpoint requires a POST request.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$event = $this->Event->fetchSimpleEvent($this->Auth->User(), $id);
|
$event = $this->Event->fetchSimpleEvent($this->Auth->user(), $id);
|
||||||
if (empty($event)) {
|
if (empty($event)) {
|
||||||
throw new MethodNotAllowedException(__('Invalid Event'));
|
throw new MethodNotAllowedException(__('Invalid Event'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,8 @@ App::uses('AppModel', 'Model');
|
||||||
class EventLock extends AppModel
|
class EventLock extends AppModel
|
||||||
{
|
{
|
||||||
// In seconds
|
// In seconds
|
||||||
const DEFAULT_TTL = 900;
|
const DEFAULT_TTL = 900,
|
||||||
|
PREFIX = 'misp:event_lock';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $user
|
* @param array $user
|
||||||
|
@ -14,7 +15,7 @@ class EventLock extends AppModel
|
||||||
*/
|
*/
|
||||||
public function insertLock(array $user, $eventId)
|
public function insertLock(array $user, $eventId)
|
||||||
{
|
{
|
||||||
return $this->insertLockToRedis("misp:event_lock:$eventId:user:{$user['id']}", [
|
return $this->insertLockToRedis($eventId, "user:{$user['id']}", [
|
||||||
'type' => 'user',
|
'type' => 'user',
|
||||||
'timestamp' => time(),
|
'timestamp' => time(),
|
||||||
'User' => [
|
'User' => [
|
||||||
|
@ -32,7 +33,7 @@ class EventLock extends AppModel
|
||||||
*/
|
*/
|
||||||
public function insertLockBackgroundJob($eventId, $jobId)
|
public function insertLockBackgroundJob($eventId, $jobId)
|
||||||
{
|
{
|
||||||
return $this->insertLockToRedis("misp:event_lock:$eventId:job:$jobId", [
|
return $this->insertLockToRedis($eventId, "job:$jobId", [
|
||||||
'type' => 'job',
|
'type' => 'job',
|
||||||
'timestamp' => time(),
|
'timestamp' => time(),
|
||||||
'job_id' => $jobId,
|
'job_id' => $jobId,
|
||||||
|
@ -45,21 +46,38 @@ class EventLock extends AppModel
|
||||||
*/
|
*/
|
||||||
public function insertLockApi($eventId, array $user)
|
public function insertLockApi($eventId, array $user)
|
||||||
{
|
{
|
||||||
$rand = mt_rand();
|
$apiLockId = mt_rand();
|
||||||
if ($this->insertLockToRedis("misp:event_lock:$eventId:api:{$user['id']}:$rand", [
|
if ($this->insertLockToRedis($eventId, "api:{$user['id']}:$apiLockId", [
|
||||||
'type' => 'api',
|
'type' => 'api',
|
||||||
'user_id' => $user['id'],
|
'user_id' => $user['id'],
|
||||||
'timestamp' => time(),
|
'timestamp' => time(),
|
||||||
])) {
|
])) {
|
||||||
return $rand;
|
return $apiLockId;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $eventId
|
||||||
|
* @param int $apiLockId
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function deleteApiLock($eventId, $apiLockId, array $user)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$redis = $this->setupRedisWithException();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$deleted = $redis->hdel(self::PREFIX . $eventId, "api:{$user['id']}:$apiLockId");
|
||||||
|
return $deleted > 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $eventId
|
* @param int $eventId
|
||||||
* @param int $jobId
|
* @param int $jobId
|
||||||
* @return null
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function deleteBackgroundJobLock($eventId, $jobId)
|
public function deleteBackgroundJobLock($eventId, $jobId)
|
||||||
{
|
{
|
||||||
|
@ -69,40 +87,7 @@ class EventLock extends AppModel
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$deleted = $redis->del("misp:event_lock:$eventId:job:$jobId");
|
$deleted = $redis->hDel(self::PREFIX . $eventId, "job:$jobId");
|
||||||
return $deleted > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $key
|
|
||||||
* @param array $data
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
private function insertLockToRedis($key, array $data)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$redis = $this->setupRedisWithException();
|
|
||||||
} catch (Exception $e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $redis->setex($key, self::DEFAULT_TTL, json_encode($data));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $eventId
|
|
||||||
* @param int $lockId
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function deleteApiLock($eventId, $lockId, array $user)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$redis = $this->setupRedisWithException();
|
|
||||||
} catch (Exception $e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$deleted = $redis->del("misp:event_lock:$eventId:api:{$user['id']}:$lockId");
|
|
||||||
return $deleted > 0;
|
return $deleted > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,13 +105,39 @@ class EventLock extends AppModel
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$keys = $redis->keys("misp:event_lock:$eventId:*");
|
$keys = $redis->hGetAll(self::PREFIX . $eventId);
|
||||||
if (empty($keys)) {
|
if (empty($keys)) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return array_map(function ($value) {
|
$output = [];
|
||||||
return $this->jsonDecode($value);
|
$now = time();
|
||||||
}, $redis->mget($keys));
|
foreach ($keys as $value) {
|
||||||
|
$value = $this->jsonDecode($value);
|
||||||
|
if ($value['timestamp'] + self::DEFAULT_TTL > $now) {
|
||||||
|
$output[] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $eventId
|
||||||
|
* @param string $lockId
|
||||||
|
* @param array $data
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function insertLockToRedis($eventId, $lockId, array $data)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$redis = $this->setupRedisWithException();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pipeline = $redis->pipeline();
|
||||||
|
$pipeline->hSet(self::PREFIX . $eventId, $lockId, json_encode($data));
|
||||||
|
$pipeline->expire(self::PREFIX . $eventId, self::DEFAULT_TTL); // prolong TTL
|
||||||
|
return $pipeline->exec()[0] !== false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue