Skip to content

Commit

Permalink
update docs and change from ResolveCache to WarmupCache
Browse files Browse the repository at this point in the history
  • Loading branch information
mynameisbogdan committed Oct 7, 2021
1 parent e519288 commit 37e7285
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 48 deletions.
15 changes: 15 additions & 0 deletions DependencyInjection/LiipImagineExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Mime\MimeTypeGuesserInterface;
use Symfony\Component\Mime\MimeTypes;

Expand Down Expand Up @@ -83,6 +85,10 @@ public function load(array $configs, ContainerBuilder $container)
$loader->load('imagine.xml');
$loader->load('commands.xml');

if ($this->isConfigEnabled($container, $config['messenger'])) {
$this->registerMessengerConfiguration($loader);
}

if ($config['enqueue']) {
$loader->load('enqueue.xml');
}
Expand Down Expand Up @@ -162,6 +168,15 @@ private function createFactories(array $factories, array $configurations, Contai
}
}

private function registerMessengerConfiguration(XmlFileLoader $loader): void
{
if (!interface_exists(MessageBusInterface::class)) {
throw new LogicException('Messenger support cannot be enabled as the Messenger component is not installed. Try running "composer require symfony/messenger".');
}

$loader->load('messenger.xml');
}

private function deprecationTemplatingFilterHelper(ContainerBuilder $container): void
{
if (!$container->hasDefinition('liip_imagine.templating.filter_helper')) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@
namespace Liip\ImagineBundle\Message\Handler;

use Liip\ImagineBundle\Imagine\Filter\FilterManager;
use Liip\ImagineBundle\Message\ResolveCache;
use Liip\ImagineBundle\Message\WarmupCache;
use Liip\ImagineBundle\Service\FilterService;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;

/** @experimental */
class ResolveCacheHandler implements MessageHandlerInterface
/**
* Listen to WarmupCache messages and prepare the cache for those images.
*
* @experimental
*/
class WarmupCacheHandler implements MessageHandlerInterface
{
/** @var FilterManager */
private $filterManager;
Expand All @@ -31,7 +35,7 @@ public function __construct(FilterManager $filterManager, FilterService $filterS
$this->filterService = $filterService;
}

public function __invoke(ResolveCache $message): void
public function __invoke(WarmupCache $message): void
{
$filters = $message->getFilters() ?: array_keys($this->filterManager->getFilterConfiguration()->all());
$path = $message->getPath();
Expand Down
10 changes: 8 additions & 2 deletions Message/ResolveCache.php → Message/WarmupCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,14 @@

namespace Liip\ImagineBundle\Message;

/** @experimental */
class ResolveCache
/**
* Message to warm up the cache for an image.
*
* Your application needs to dispatch this message when it becomes aware of a new image.
*
* @experimental
*/
class WarmupCache
{
/**
* @var string
Expand Down
9 changes: 4 additions & 5 deletions Resources/config/messenger.xml
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="liip_imagine.messenger.resolve_cache_processor" class="Liip\ImagineBundle\Message\Handler\ResolveCacheHandler" public="false">
<service id="liip_imagine.messenger.warmup_cache_processor" class="Liip\ImagineBundle\Message\Handler\WarmupCacheHandler" public="false">
<argument type="service" id="liip_imagine.filter.manager"/>
<argument type="service" id="liip_imagine.service.filter"/>
<tag name="messenger.message_handler" handles="Liip\ImagineBundle\Message\ResolveCache"/>
<tag name="messenger.message_handler" handles="Liip\ImagineBundle\Message\WarmupCache"/>
</service>
</services>
</container>
45 changes: 23 additions & 22 deletions Resources/doc/resolve-cache-images-in-background.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ Though there are some disadvantages:
If there is nothing in the cache the page will contain the url to resolve controller.
The varnish may cache the page with those links to the resolve controller.
A browser keeps sending requests to it though there is no need for it after the first call.
To prepare the cached images in advance, the LiipImagineBundle allows you to use a message queue to have a worker warm up the cache asynchronously. Your application has to send messages about the images as it becomes aware of them (file upload, import processes, ...) and you need to run the worker for the message queue.

Messenger
Symfony Messenger
-------------------

Step 1: Install
~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~

First, we have to `install symfony/messenger`_. You have to basically use composer to install the Symfony component.
First, `install symfony/messenger`_ with composer:

.. code-block:: terminal
Expand All @@ -34,15 +35,15 @@ First, we have to `install symfony/messenger`_. You have to basically use compos
messenger:
transports:
# https://symfony.com/doc/current/messenger.html#transport-configuration
async: '%env(MESSENGER_TRANSPORT_DSN)%'
liip_imagine: '%env(MESSENGER_TRANSPORT_DSN)%'
sync: 'sync://'
routing:
# Route your messages to the transports
'Liip\ImagineBundle\Message\ResolveCache': async
'Liip\ImagineBundle\Message\WarmupCache': liip_imagine
Step 2: Configure LiipImagineBundle
~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

At this step we instruct LiipImagineBundle to load some extra stuff required to process images in background.

Expand All @@ -54,32 +55,32 @@ At this step we instruct LiipImagineBundle to load some extra stuff required to
messenger: true
Step 3: Run consumers
~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~

Before we can start using it we need a pool of consumers (at least one) to be working in background.
Here's how you can run it:

.. code-block:: terminal
$ php bin/console messenger:consume async --time-limit=3600 --memory-limit=256M
$ php bin/console messenger:consume liip_imagine --time-limit=3600 --memory-limit=256M
# use -vv to see details about what's happening
$ php bin/console messenger:consume async --time-limit=3600 --memory-limit=256M -vv
$ php bin/console messenger:consume liip_imagine --time-limit=3600 --memory-limit=256M -vv
Step 4: Send resolve cache message
~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

You have to dispatch a message in order to process images in background.
The message must contain the original image path (in terms of LiipImagineBundle).
If you do not define filters the background process will resolve cache for all available filters.
If the cache already exist the background process does recreate it by default
If you do not define filters, the background process will resolve cache for all available filters.
If the cache already exists, the background process does not recreate it by default.
You can force cache to be recreated and in this case the cached image is removed and a new one replaces it.

.. code-block:: php
<?php
use Liip\ImagineBundle\Message\ResolveCache;
use Liip\ImagineBundle\Message\WarmupCache;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Messenger\MessageBusInterface;
Expand All @@ -88,13 +89,13 @@ You can force cache to be recreated and in this case the cached image is removed
public function index(MessageBusInterface $messageBus)
{
// resolve all caches
$messageBus->dispatch(new ResolveCache('the/path/img.png'));
$messageBus->dispatch(new WarmupCache('the/path/img.png'));
// resolve specific cache
$messageBus->dispatch(new ResolveCache('the/path/img.png', ['fooFilter']));
$messageBus->dispatch(new WarmupCache('the/path/img.png', ['fooFilter']));
// force resolve (removes the cache if exists)
$messageBus->dispatch(new ResolveCache('the/path/img.png', null, true));
$messageBus->dispatch(new WarmupCache('the/path/img.png', null, true));
}
}
Expand All @@ -105,7 +106,7 @@ The bundle provides a solution. It utilize messaging pattern and works on top of


Step 1: Install EnqueueBundle
~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

First, we have to `install EnqueueBundle`_. You have to basically use composer to install the bundle,
register it to AppKernel and adjust settings. Here's the most simplest configuration without any extra dependencies.
Expand All @@ -121,7 +122,7 @@ It is based on `filesystem transport`_.
client: ~
Step 2: Configure LiipImagineBundle
~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

At this step we instruct LiipImagineBundle to load some extra stuff required to process images in background.

Expand All @@ -133,7 +134,7 @@ At this step we instruct LiipImagineBundle to load some extra stuff required to
enqueue: true
Step 3: Run consumers
~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~

Before we can start using it we need a pool of consumers (at least one) to be working in background.
Here's how you can run it:
Expand All @@ -143,12 +144,12 @@ Here's how you can run it:
$ ./app/console enqueue:consume --setup-broker -vvv
Step 4: Send resolve cache message
~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

You have to send a message in order to process images in background.
The message must contain the original image path (in terms of LiipImagineBundle).
If you do not define filters the background process will resolve cache for all available filters.
If the cache already exist the background process does recreate it by default
If you do not define filters, the background process will resolve cache for all available filters.
If the cache already exists, the background process does not recreate it by default.
You can force cache to be recreated and in this case the cached image is removed and a new one replaces it.

.. code-block:: php
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

use Liip\ImagineBundle\Exception\Binary\Loader\NotLoadableException;
use Liip\ImagineBundle\Imagine\Filter\FilterManager;
use Liip\ImagineBundle\Message\Handler\ResolveCacheHandler;
use Liip\ImagineBundle\Message\ResolveCache;
use Liip\ImagineBundle\Message\Handler\WarmupCacheHandler;
use Liip\ImagineBundle\Message\WarmupCache;
use Liip\ImagineBundle\Service\FilterService;
use Liip\ImagineBundle\Tests\Functional\AbstractWebTestCase;
use ReflectionClass;
Expand All @@ -26,9 +26,9 @@
/**
* @requires PHP 7.1
*
* @covers \Liip\ImagineBundle\Message\Handler\ResolveCacheHandler
* @covers \Liip\ImagineBundle\Message\Handler\WarmupCacheHandler
*/
class ResolveCacheHandlerTest extends AbstractWebTestCase
class WarmupCacheHandlerTest extends AbstractWebTestCase
{
protected function setUp(): void
{
Expand All @@ -39,7 +39,7 @@ protected function setUp(): void

public function testShouldImplementMessageHandlerInterface(): void
{
$rc = new ReflectionClass(ResolveCacheHandler::class);
$rc = new ReflectionClass(WarmupCacheHandler::class);

$this->assertTrue($rc->implementsInterface(MessageHandlerInterface::class));
}
Expand All @@ -48,27 +48,27 @@ public function testCouldBeConstructedWithExpectedArguments(): void
{
static::createClient();

$handler = new ResolveCacheHandler(
$handler = new WarmupCacheHandler(
$this->createFilterManagerMock(),
$this->createFilterServiceMock()
);

$this->assertInstanceOf(ResolveCacheHandler::class, $handler);
$this->assertInstanceOf(WarmupCacheHandler::class, $handler);
}

public function testThrowIfMessageMissingPath(): void
{
static::createClient();

$handler = new ResolveCacheHandler(
$handler = new WarmupCacheHandler(
$this->createFilterManagerMock(),
$this->createFilterServiceMock()
);

$this->expectException(NotLoadableException::class);
$this->expectExceptionMessage('Source image not resolvable "thePath"');

$handler->__invoke(new ResolveCache('thePath', null, true));
$handler->__invoke(new WarmupCache('thePath', null, true));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@

namespace Liip\ImagineBundle\Tests\Message;

use Liip\ImagineBundle\Message\ResolveCache;
use Liip\ImagineBundle\Message\WarmupCache;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Messenger\MessageBusInterface;

/**
* @covers \Liip\ImagineBundle\Message\ResolveCache
* @covers \Liip\ImagineBundle\Message\WarmupCache
*/
class ResolveCacheTest extends TestCase
class WarmupCacheTest extends TestCase
{
protected function setUp(): void
{
Expand All @@ -31,7 +31,7 @@ protected function setUp(): void

public function testMessageWithoutFiltersAndForce(): void
{
$message = new ResolveCache('thePath');
$message = new WarmupCache('thePath');

$this->assertSame('thePath', $message->getPath());
$this->assertNull($message->getFilters());
Expand All @@ -40,7 +40,7 @@ public function testMessageWithoutFiltersAndForce(): void

public function testMessageWithFilters(): void
{
$message = new ResolveCache('thePath', ['fooFilter', 'barFilter']);
$message = new WarmupCache('thePath', ['fooFilter', 'barFilter']);

$this->assertSame('thePath', $message->getPath());
$this->assertSame(['fooFilter', 'barFilter'], $message->getFilters());
Expand All @@ -49,7 +49,7 @@ public function testMessageWithFilters(): void

public function testMessageWithFiltersAndForce(): void
{
$message = new ResolveCache('thePath', ['fooFilter', 'barFilter'], true);
$message = new WarmupCache('thePath', ['fooFilter', 'barFilter'], true);

$this->assertSame('thePath', $message->getPath());
$this->assertSame(['fooFilter', 'barFilter'], $message->getFilters());
Expand Down

0 comments on commit 37e7285

Please sign in to comment.