Skip to content

Commit

Permalink
NGSTACK-805: implement support for asynchronous indexing
Browse files Browse the repository at this point in the history
  • Loading branch information
pspanja committed Nov 13, 2023
1 parent 52b6b82 commit f86ed43
Show file tree
Hide file tree
Showing 90 changed files with 2,730 additions and 240 deletions.
12 changes: 12 additions & 0 deletions bundle/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public function getConfigTreeBuilder(): TreeBuilder

$this->addIndexableFieldTypeSection($rootNode);
$this->addSearchResultExtractorSection($rootNode);
$this->addAsynchronousIndexingSection($rootNode);

return $treeBuilder;
}
Expand Down Expand Up @@ -61,4 +62,15 @@ private function addSearchResultExtractorSection(ArrayNodeDefinition $nodeDefini
->end()
->end();
}

private function addAsynchronousIndexingSection(ArrayNodeDefinition $nodeDefinition): void
{
$nodeDefinition
->children()
->booleanNode('use_asynchronous_indexing')
->info('Use asynchronous mechanism to handle repository content indexing')
->defaultFalse()
->end()
->end();
}
}
10 changes: 10 additions & 0 deletions bundle/DependencyInjection/NetgenIbexaSearchExtraExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;

use function array_key_exists;

class NetgenIbexaSearchExtraExtension extends Extension
Expand Down Expand Up @@ -69,6 +70,7 @@ private function processExtensionConfiguration(array $configs, ContainerBuilder

$this->processIndexableFieldTypeConfiguration($configuration, $container);
$this->processSearchResultExtractorConfiguration($configuration, $container);
$this->processAsynchronousIndexingConfiguration($configuration, $container);
}

private function processSearchResultExtractorConfiguration(array $configuration, ContainerBuilder $container): void
Expand All @@ -90,4 +92,12 @@ private function processIndexableFieldTypeConfiguration(array $configuration, Co
$configuration['indexable_field_type']['ezrichtext']['short_text_limit'],
);
}

private function processAsynchronousIndexingConfiguration(array $configuration, ContainerBuilder $container): void
{
$container->setParameter(
'netgen_ibexa_search_extra.use_asynchronous_indexing',
$configuration['use_asynchronous_indexing'],
);
}
}
1 change: 1 addition & 0 deletions bundle/NetgenIbexaSearchExtraBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public function build(ContainerBuilder $container): void
$container->addCompilerPass(new Compiler\AggregateContentTranslationSubdocumentMapperPass());
$container->addCompilerPass(new Compiler\AggregateFacetBuilderVisitorPass());
$container->addCompilerPass(new Compiler\AggregateSubdocumentQueryCriterionVisitorPass());
$container->addCompilerPass(new Compiler\AsynchronousIndexingPass());
$container->addCompilerPass(new Compiler\FieldType\RichTextIndexablePass());
$container->addCompilerPass(new Compiler\SearchResultExtractorPass());
$container->addCompilerPass(new Compiler\RawFacetBuilderDomainVisitorPass());
Expand Down
52 changes: 52 additions & 0 deletions bundle/Resources/config/messenger.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# This is an example Symfony Messenger component configuration for asynchronous indexing.
# Use it if it fits your needs, or create your own as you require.
framework:
messenger:
reset_on_message: true
transports:
netgen_ibexa_asynchronous_indexing:
dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
failure_transport: netgen_ibexa_asynchronous_indexing_failed
retry_strategy:
max_retries: 5
delay: 1000
multiplier: 3
max_delay: 600000
options:
redeliver_timeout: 300
queue_name: netgen_ibexa_asynchronous_indexing
netgen_ibexa_asynchronous_indexing_failed: "doctrine://default?queue_name=netgen_ibexa_asynchronous_indexing_failed"
routing:
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\CopyContent': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\DeleteContent': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\DeleteTranslation': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\HideContent': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\PublishVersion': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\RevealContent': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\UpdateContentMetadata': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Location\AssignSectionToSubtree': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Location\CopySubtree': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Location\CreateLocation': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Location\DeleteLocation': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Location\HideLocation': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Location\MoveSubtree': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Location\SwapLocation': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Location\UnhideLocation': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Location\UpdateLocation': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\ObjectState\SetContentState': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Section\AssignSection': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Trash\Recover': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Trash\Trash': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\User\AssignUserToUserGroup': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\User\BeforeUnAssignUserFromUserGroup': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\User\CreateUserGroup': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\User\CreateUser': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\User\DeleteUserGroup': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\User\DeleteUser': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\User\MoveUserGroup': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\User\UnAssignUserFromUserGroup': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\User\UpdateUserGroup': netgen_ibexa_asynchronous_indexing
'Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\User\UpdateUser': netgen_ibexa_asynchronous_indexing
default_bus: messenger.bus.default
buses:
messenger.bus.default: ~
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
"symfony/proxy-manager-bridge": "^5.4"
},
"require-dev": {
"ibexa/fieldtype-richtext": "^4.5",
"ibexa/solr": "^4.5",
"symfony/messenger": "^5.4",
"phpunit/phpunit": "^8.5",
"matthiasnoback/symfony-dependency-injection-test": "^4.1",
"behat/behat": "^3.6.1",
Expand Down
77 changes: 77 additions & 0 deletions lib/Container/Compiler/AsynchronousIndexingPass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

declare(strict_types=1);

namespace Netgen\IbexaSearchExtra\Container\Compiler;

use Ibexa\Core\Search\Common\EventSubscriber\ContentEventSubscriber as CoreContentEventSubscriber;
use Ibexa\Core\Search\Common\EventSubscriber\LocationEventSubscriber as CoreLocationEventSubscriber;
use Ibexa\Core\Search\Common\EventSubscriber\ObjectStateEventSubscriber as CoreObjectStateEventSubscriber;
use Ibexa\Core\Search\Common\EventSubscriber\SectionEventSubscriber as CoreSectionEventSubscriber;
use Ibexa\Core\Search\Common\EventSubscriber\TrashEventSubscriber as CoreTrashEventSubscriber;
use Ibexa\Core\Search\Common\EventSubscriber\UserEventSubscriber as CoreUserEventSubscriber;
use Netgen\IbexaSearchExtra\Core\Search\Common\EventSubscriber\ContentEventSubscriber;
use Netgen\IbexaSearchExtra\Core\Search\Common\EventSubscriber\LocationEventSubscriber;
use Netgen\IbexaSearchExtra\Core\Search\Common\EventSubscriber\ObjectStateEventSubscriber;
use Netgen\IbexaSearchExtra\Core\Search\Common\EventSubscriber\SectionEventSubscriber;
use Netgen\IbexaSearchExtra\Core\Search\Common\EventSubscriber\TrashEventSubscriber;
use Netgen\IbexaSearchExtra\Core\Search\Common\EventSubscriber\UserEventSubscriber;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

final class AsynchronousIndexingPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container): void
{
$useAsynchronousIndexing = $container->getParameter(
'netgen_ibexa_search_extra.use_asynchronous_indexing',
);

if ($useAsynchronousIndexing !== true) {
return;
}

$container
->register(ContentEventSubscriber::class, ContentEventSubscriber::class)
->setDecoratedService(CoreContentEventSubscriber::class)
->setArguments([
new Reference('netgen.ibexa_search_extra.asynchronous_indexing.messenger.bus'),
]);

$container
->register(LocationEventSubscriber::class, LocationEventSubscriber::class)
->setDecoratedService(CoreLocationEventSubscriber::class)
->setArguments([
new Reference('netgen.ibexa_search_extra.asynchronous_indexing.messenger.bus'),
]);

$container
->register(ObjectStateEventSubscriber::class, ObjectStateEventSubscriber::class)
->setDecoratedService(CoreObjectStateEventSubscriber::class)
->setArguments([
new Reference('netgen.ibexa_search_extra.asynchronous_indexing.messenger.bus'),
]);

$container
->register(SectionEventSubscriber::class, SectionEventSubscriber::class)
->setDecoratedService(CoreSectionEventSubscriber::class)
->setArguments([
new Reference('netgen.ibexa_search_extra.asynchronous_indexing.messenger.bus'),
]);

$container
->register(TrashEventSubscriber::class, TrashEventSubscriber::class)
->setDecoratedService(CoreTrashEventSubscriber::class)
->setArguments([
new Reference('netgen.ibexa_search_extra.asynchronous_indexing.messenger.bus'),
]);

$container
->register(UserEventSubscriber::class, UserEventSubscriber::class)
->setDecoratedService(CoreUserEventSubscriber::class)
->setArguments([
new Reference('netgen.ibexa_search_extra.asynchronous_indexing.messenger.bus'),
]);
}
}
109 changes: 109 additions & 0 deletions lib/Core/Search/Common/EventSubscriber/ContentEventSubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php

declare(strict_types=1);

namespace Netgen\IbexaSearchExtra\Core\Search\Common\EventSubscriber;

use Ibexa\Contracts\Core\Repository\Events\Content\CopyContentEvent;
use Ibexa\Contracts\Core\Repository\Events\Content\DeleteContentEvent;
use Ibexa\Contracts\Core\Repository\Events\Content\DeleteTranslationEvent;
use Ibexa\Contracts\Core\Repository\Events\Content\HideContentEvent;
use Ibexa\Contracts\Core\Repository\Events\Content\PublishVersionEvent;
use Ibexa\Contracts\Core\Repository\Events\Content\RevealContentEvent;
use Ibexa\Contracts\Core\Repository\Events\Content\UpdateContentMetadataEvent;
use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\CopyContent;
use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\DeleteContent;
use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\DeleteTranslation;
use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\HideContent;
use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\PublishVersion;
use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\RevealContent;
use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\UpdateContentMetadata;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Messenger\MessageBusInterface;

class ContentEventSubscriber implements EventSubscriberInterface
{
public function __construct(
private readonly MessageBusInterface $messageBus,
) {}

public static function getSubscribedEvents(): array
{
return [
CopyContentEvent::class => 'onCopyContent',
DeleteContentEvent::class => 'onDeleteContent',
DeleteTranslationEvent::class => 'onDeleteTranslation',
HideContentEvent::class => 'onHideContent',
PublishVersionEvent::class => 'onPublishVersion',
RevealContentEvent::class => 'onRevealContent',
UpdateContentMetadataEvent::class => 'onUpdateContentMetadata',
];
}

public function onCopyContent(CopyContentEvent $event): void
{
$this->messageBus->dispatch(
new CopyContent(
$event->getContent()->getVersionInfo()->getContentInfo()->id,
$event->getContent()->getVersionInfo()->versionNo,
),
);
}

public function onDeleteContent(DeleteContentEvent $event): void
{
$this->messageBus->dispatch(
new DeleteContent(
$event->getContentInfo()->id,
$event->getLocations(),
),
);
}

public function onDeleteTranslation(DeleteTranslationEvent $event): void
{
$this->messageBus->dispatch(
new DeleteTranslation(
$event->getContentInfo()->id,
$event->getLanguageCode(),
),
);
}

public function onHideContent(HideContentEvent $event): void
{
$this->messageBus->dispatch(
new HideContent(
$event->getContentInfo()->id,
),
);
}

public function onPublishVersion(PublishVersionEvent $event): void
{
$this->messageBus->dispatch(
new PublishVersion(
$event->getContent()->id,
$event->getContent()->getVersionInfo()->versionNo,
),
);
}

public function onRevealContent(RevealContentEvent $event): void
{
$this->messageBus->dispatch(
new RevealContent(
$event->getContentInfo()->id,
),
);
}

public function onUpdateContentMetadata(UpdateContentMetadataEvent $event): void
{
$this->messageBus->dispatch(
new UpdateContentMetadata(
$event->getContentInfo()->id,
),
);
}
}
Loading

0 comments on commit f86ed43

Please sign in to comment.