FEATURE: Provide basic caching

This commit is contained in:
Daniel Siepmann 2018-12-30 14:48:17 +01:00
parent 4c99009ea0
commit f955a9b70a
Signed by: Daniel Siepmann
GPG key ID: 33D6629915560EF4
7 changed files with 77 additions and 3 deletions

View file

@ -188,6 +188,20 @@ class SearchRequest implements SearchRequestInterface
return $this->offset; return $this->offset;
} }
/**
* Used, e.g. by caching to determine identifier.
*/
public function __sleep()
{
return [
'query',
'filter',
'facets',
'offset',
'limit',
];
}
/** /**
* @throws \BadMethodCallException * @throws \BadMethodCallException
*/ */

View file

@ -30,6 +30,8 @@ use Codappix\SearchCore\DataProcessing\Service as DataProcessorService;
use Codappix\SearchCore\Domain\Model\FacetRequest; use Codappix\SearchCore\Domain\Model\FacetRequest;
use Codappix\SearchCore\Domain\Model\SearchResult; use Codappix\SearchCore\Domain\Model\SearchResult;
use Codappix\SearchCore\Utility\ArrayUtility; use Codappix\SearchCore\Utility\ArrayUtility;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface; use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
/** /**
@ -57,22 +59,30 @@ class SearchService implements SearchServiceInterface
*/ */
protected $dataProcessorService; protected $dataProcessorService;
/**
* @var FrontendInterface
*/
protected $cache;
/** /**
* @param ConnectionInterface $connection * @param ConnectionInterface $connection
* @param ConfigurationContainerInterface $configuration * @param ConfigurationContainerInterface $configuration
* @param ObjectManagerInterface $objectManager * @param ObjectManagerInterface $objectManager
* @param DataProcessorService $dataProcessorService * @param DataProcessorService $dataProcessorService
* @param CacheManager $cacheManager
*/ */
public function __construct( public function __construct(
ConnectionInterface $connection, ConnectionInterface $connection,
ConfigurationContainerInterface $configuration, ConfigurationContainerInterface $configuration,
ObjectManagerInterface $objectManager, ObjectManagerInterface $objectManager,
DataProcessorService $dataProcessorService DataProcessorService $dataProcessorService,
CacheManager $cacheManager
) { ) {
$this->connection = $connection; $this->connection = $connection;
$this->configuration = $configuration; $this->configuration = $configuration;
$this->objectManager = $objectManager; $this->objectManager = $objectManager;
$this->dataProcessorService = $dataProcessorService; $this->dataProcessorService = $dataProcessorService;
$this->cache = $cacheManager->getCache('search_core');
} }
public function search(SearchRequestInterface $searchRequest): SearchResultInterface public function search(SearchRequestInterface $searchRequest): SearchResultInterface
@ -85,7 +95,15 @@ class SearchService implements SearchServiceInterface
$searchRequest->setConnection($this->connection); $searchRequest->setConnection($this->connection);
$searchRequest->setSearchService($this); $searchRequest->setSearchService($this);
return $this->processResult($this->connection->search($searchRequest)); $identifier = sha1('search' . serialize($searchRequest));
if ($this->cache->has($identifier)) {
return $this->cache->get($identifier);
}
$result = $this->processResult($this->connection->search($searchRequest));
$this->cache->set($identifier, $result);
return $result;
} }
/** /**

View file

@ -4,6 +4,7 @@ v0.1.0
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
0.1.0/2018-added-caching
0.1.0/2018-added-content-element-wizard 0.1.0/2018-added-content-element-wizard
0.1.0/2018-changed-interfaces 0.1.0/2018-changed-interfaces
0.1.0/2018-elasticsearch-upgrade 0.1.0/2018-elasticsearch-upgrade

View file

@ -0,0 +1,22 @@
Feature "Added caching"
=======================
Processing searches are now cacheable, the TYPO3 caching framework is used for
caching. By default the ``NullBackend`` is used to keep old behaviour, which matches
searches the best.
Still if the same search is run multiple times during a single request, the
``TransientMemoryBackend`` is a nice option.
Depending on search backend, one might also use a different backend for caching and
configure some TTL.
.. note::
Paging is currently not supported for caching.
Using ``NullBackend`` or ``TransientMemoryBackend`` will work, but using persistent
backends in combination with fluid pagination widget will lead to errors right
now.
For further information, check out official :ref:`t3explained:caching` documentation.

View file

@ -304,6 +304,7 @@ texinfo_documents = [
intersphinx_mapping = { intersphinx_mapping = {
't3tcaref': ('https://docs.typo3.org/typo3cms/TCAReference/', None), 't3tcaref': ('https://docs.typo3.org/typo3cms/TCAReference/', None),
't3tsref': ('https://docs.typo3.org/typo3cms/TyposcriptReference/', None), 't3tsref': ('https://docs.typo3.org/typo3cms/TyposcriptReference/', None),
't3explained': ('https://docs.typo3.org/typo3cms/CoreApiReference/', None),
} }
extlinks = { extlinks = {
'project': ('https://github.com/Codappix/search_core/projects/%s', 'Github project: '), 'project': ('https://github.com/Codappix/search_core/projects/%s', 'Github project: '),

View file

@ -30,6 +30,8 @@ use Codappix\SearchCore\Domain\Model\SearchRequest;
use Codappix\SearchCore\Domain\Model\SearchResult; use Codappix\SearchCore\Domain\Model\SearchResult;
use Codappix\SearchCore\Domain\Search\SearchService; use Codappix\SearchCore\Domain\Search\SearchService;
use Codappix\SearchCore\Tests\Unit\AbstractUnitTestCase; use Codappix\SearchCore\Tests\Unit\AbstractUnitTestCase;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface; use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
class SearchServiceTest extends AbstractUnitTestCase class SearchServiceTest extends AbstractUnitTestCase
@ -68,6 +70,13 @@ class SearchServiceTest extends AbstractUnitTestCase
{ {
parent::setUp(); parent::setUp();
$cacheMock = $this->getMockBuilder(FrontendInterface::class)->getMock();
$cacheManagerMock = $this->getMockBuilder(CacheManager::class)->getMock();
$cacheManagerMock->expects($this->any())
->method('getCache')
->with('search_core')
->willReturn($cacheMock);
$this->result = $this->getMockBuilder(SearchResultInterface::class) $this->result = $this->getMockBuilder(SearchResultInterface::class)
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock(); ->getMock();
@ -88,7 +97,8 @@ class SearchServiceTest extends AbstractUnitTestCase
$this->connection, $this->connection,
$this->configuration, $this->configuration,
$this->objectManager, $this->objectManager,
$this->dataProcessorService $this->dataProcessorService,
$cacheManagerMock
); );
} }

View file

@ -54,6 +54,14 @@
'<INCLUDE_TYPOSCRIPT: source="FILE:EXT:' . $extension . '/Configuration/TSconfig/Page/Mod/Wizards/NewContentElement.tsconfig">' '<INCLUDE_TYPOSCRIPT: source="FILE:EXT:' . $extension . '/Configuration/TSconfig/Page/Mod/Wizards/NewContentElement.tsconfig">'
); );
if (!is_array($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['search_core'])) {
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['search_core'] = [];
}
if (!isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['search_core']['backend'])) {
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['search_core']['backend'] =
\TYPO3\CMS\Core\Cache\Backend\NullBackend::class;
}
if (empty($configuration) || if (empty($configuration) ||
(isset($configuration['disable.']['elasticsearch']) && (isset($configuration['disable.']['elasticsearch']) &&
filter_var($configuration['disable.']['elasticsearch'], FILTER_VALIDATE_BOOLEAN) === false) filter_var($configuration['disable.']['elasticsearch'], FILTER_VALIDATE_BOOLEAN) === false)