fix: Move caching to the mapper instead

Application class cannot use DI, and having the cache in the mapper
 allows for invalidating it when inserting or updating a webhook
 registration.

Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
This commit is contained in:
Côme Chilliet 2024-06-06 17:00:45 +02:00 committed by Côme Chilliet
parent 98f3ea657c
commit 3bc43b2a34
2 changed files with 37 additions and 30 deletions

View file

@ -16,25 +16,14 @@ use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\ICache;
use OCP\ICacheFactory;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
class Application extends App implements IBootstrap {
public const APP_ID = 'webhooks';
private ?ICache $cache = null;
private const CACHE_KEY = 'eventsUsedInWebhooks';
public function __construct(
ICacheFactory $cacheFactory,
) {
public function __construct() {
parent::__construct(self::APP_ID);
if ($cacheFactory->isAvailable()) {
$this->cache = $cacheFactory->createDistributed();
}
}
public function register(IRegistrationContext $context): void {
@ -49,8 +38,11 @@ class Application extends App implements IBootstrap {
ContainerInterface $container,
LoggerInterface $logger,
): void {
/** @var WebhookListenerMapper */
$mapper = $container->get(WebhookListenerMapper::class);
/* Listen to all events with at least one webhook configured */
$configuredEvents = $this->getAllConfiguredEvents($container);
$configuredEvents = $mapper->getAllConfiguredEvents();
foreach ($configuredEvents as $eventName) {
$logger->debug("Listening to {$eventName}");
$dispatcher->addServiceListener(
@ -60,19 +52,4 @@ class Application extends App implements IBootstrap {
);
}
}
/**
* List all events with at least one webhook configured, with cache
*/
private function getAllConfiguredEvents(ContainerInterface $container) {
$events = $this->cache?->get(self::CACHE_KEY);
if ($events !== null) {
return json_decode($events);
}
/** @var WebhookListenerMapper */
$mapper = $container->get(WebhookListenerMapper::class);
$events = $mapper->getAllConfiguredEvents();
// cache for 5 minutes
$this->cache?->set(self::CACHE_KEY, json_encode($events), 300);
}
}

View file

@ -15,6 +15,8 @@ use OCP\AppFramework\Db\QBMapper;
use OCP\DB\Exception;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\EventDispatcher\IWebhookCompatibleEvent;
use OCP\ICache;
use OCP\ICacheFactory;
use OCP\IDBConnection;
/**
@ -23,8 +25,18 @@ use OCP\IDBConnection;
class WebhookListenerMapper extends QBMapper {
public const TABLE_NAME = 'webhook_listeners';
public function __construct(IDBConnection $db) {
private const EVENTS_CACHE_KEY = 'eventsUsedInWebhooks';
private ?ICache $cache = null;
public function __construct(
IDBConnection $db,
ICacheFactory $cacheFactory,
) {
parent::__construct($db, self::TABLE_NAME, WebhookListener::class);
if ($cacheFactory->isAvailable()) {
$this->cache = $cacheFactory->createDistributed();
}
}
/**
@ -85,6 +97,7 @@ class WebhookListenerMapper extends QBMapper {
]
);
$webhookListener->setAuthDataClear($authData);
$this->cache?->remove(self::EVENTS_CACHE_KEY);
return $this->insert($webhookListener);
}
@ -120,6 +133,7 @@ class WebhookListenerMapper extends QBMapper {
]
);
$webhookListener->setAuthDataClear($authData);
$this->cache?->remove(self::EVENTS_CACHE_KEY);
return $this->update($webhookListener);
}
@ -139,7 +153,7 @@ class WebhookListenerMapper extends QBMapper {
* @throws Exception
* @return list<string>
*/
public function getAllConfiguredEvents(): array {
private function getAllConfiguredEventsFromDatabase(): array {
$qb = $this->db->getQueryBuilder();
$qb->selectDistinct('event')
@ -156,6 +170,22 @@ class WebhookListenerMapper extends QBMapper {
return $configuredEvents;
}
/**
* List all events with at least one webhook configured, with cache
* @throws Exception
* @return list<string>
*/
public function getAllConfiguredEvents(): array {
$events = $this->cache?->get(self::EVENTS_CACHE_KEY);
if ($events !== null) {
return json_decode($events);
}
$events = $this->getAllConfiguredEventsFromDatabase();
// cache for 5 minutes
$this->cache?->set(self::EVENTS_CACHE_KEY, json_encode($events), 300);
return $events;
}
/**
* @throws Exception
*/