Skip to content

Commit

Permalink
Add caching support
Browse files Browse the repository at this point in the history
  • Loading branch information
GeLoLabs committed Sep 20, 2015
1 parent 6e1da2c commit 8a98333
Show file tree
Hide file tree
Showing 12 changed files with 280 additions and 3 deletions.
20 changes: 18 additions & 2 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public function getConfigTreeBuilder()
->beforeNormalization()
->always(function ($config) {
if (empty($config['adapters'])) {
$config['adapters'] = array('default' => array('type' => 'socket'));
$config['adapters'] = ['default' => ['type' => 'socket']];
}

if (!isset($config['default'])) {
Expand Down Expand Up @@ -101,6 +101,7 @@ private function createSubscribersNode()
->canBeEnabled()
->children()
->append($this->createBasicAuthSubscriberNode())
->append($this->createCacheSubscriberNode())
->append($this->createRedirectSubscriberNode())
->scalarNode('cookie')->end()
->scalarNode('history')->end()
Expand All @@ -126,6 +127,21 @@ private function createBasicAuthSubscriberNode()
->end();
}

/**
* Creates the cache subscriber node.
*
* @return \Symfony\Component\Config\Definition\Builder\NodeDefinition The cache subscriber node.
*/
private function createCacheSubscriberNode()
{
return $this->createNode('cache')
->children()
->scalarNode('adapter')->isRequired()->end()
->integerNode('lifetime')->defaultValue(null)->end()
->booleanNode('exception')->defaultValue(true)->end()
->end();
}

/**
* Creates the redirect subscriber node.
*
Expand All @@ -146,7 +162,7 @@ private function createRedirectSubscriberNode()
*
* @param string $name The node name.
*
* @return \Symfony\Component\Config\Definition\Builder\NodeDefinition The node.
* @return \Symfony\Component\Config\Definition\Builder\NodeDefinition|\Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition The node.
*/
private function createNode($name)
{
Expand Down
25 changes: 25 additions & 0 deletions DependencyInjection/IvoryHttpAdapterExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,10 @@ private function createSubscriberDefinition(
$this->configureBasicAuthSubscriberDefinition($subscriber, $configuration, $adapterName, $container);
break;

case 'cache':
$this->configureCacheSubscriberDefinition($subscriber, $configuration, $adapterName, $container);
break;

case 'cookie':
$this->configureCookieSubscriberDefinition($subscriber, $configuration);
break;
Expand Down Expand Up @@ -277,6 +281,27 @@ private function configureBasicAuthSubscriberDefinition(
$subscriber->setArguments(array(new Reference($service)));
}

/**
* Configures the cache subscriber definition.
*
* @param \Symfony\Component\DependencyInjection\Definition $subscriber The subscriber.
* @param array $cache The cache.
* @param string $adapterName The adapter name.
* @param \Symfony\Component\DependencyInjection\ContainerBuilder $container The container.
*/
private function configureCacheSubscriberDefinition(
Definition $subscriber,
array $cache,
$adapterName,
ContainerBuilder $container
) {
$model = new DefinitionDecorator(self::createServiceName('subscriber.cache.model'));
$model->setArguments(array(new Reference($cache['adapter']), null, $cache['lifetime'], $cache['exception']));

$container->setDefinition($service = self::createServiceName($adapterName.'.cache.model'), $model);
$subscriber->setArguments(array(new Reference($service)));
}

/**
* Configures the cookie subscriber definition.
*
Expand Down
20 changes: 20 additions & 0 deletions Resources/config/subscribers/cache.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" ?>

<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"
>
<services>
<service
id="ivory.http_adapter.subscriber.cache.model"
class="Ivory\HttpAdapter\Event\Cache\Cache"
abstract="true"
/>

<service
id="ivory.http_adapter.subscriber.cache"
class="Ivory\HttpAdapter\Event\Subscriber\CacheSubscriber"
abstract="true"
/>
</services>
</container>
23 changes: 23 additions & 0 deletions Resources/doc/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ ivory_http_adapter:
basic_auth:
username: egeloen
password: pass
cache:
adapter: your.adapter.service
cookie: ~
history: ~
logger: ~
Expand Down Expand Up @@ -108,6 +110,8 @@ ivory_http_adapter:
basic_auth:
username: egeloen
password: pass
cache:
adapter: your.adapter.service
cookie: ~
history: ~
logger: ~
Expand Down Expand Up @@ -140,6 +144,25 @@ basic_auth:
matcher: my-domain.com
```

### Cache subscriber

The cache subscriber requires you to create a cache adapter service which is an implementation of
`Ivory\HttpAdapter\Event\Cache\Adapter\CacheAdapterInterface`. When it is created, just configure it:

``` yaml
# ...
cache:
adapter: your.adapter.service
```

You can also specify if the exceptions should be cached (enabled by default):

``` yaml
# ...
cache:
exception: false
```

### Cookie subscriber

The cookie subscriber can use different jar implementation according to your needs. To use the file one:
Expand Down
150 changes: 150 additions & 0 deletions Tests/DependencyInjection/AbstractIvoryHttpAdapterExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,81 @@ public function testGlobalBasicAuthSubscriberWithMatcher()
$this->assertSame('domain.com', $basicAuth->getMatcher());
}

public function testGlobalCacheSubscriber()
{
$this->container->set(
'ivory.cache.adapter',
$cacheAdapter = $this->getMock('Ivory\HttpAdapter\Event\Cache\Adapter\CacheAdapterInterface')
);

$this->loadConfiguration($this->container, 'global_cache');
$this->container->compile();

$listener = $this->assertListener(
$this->container->get('ivory.http_adapter.default.event_dispatcher'),
Events::REQUEST_CREATED,
'Ivory\HttpAdapter\Event\Subscriber\CacheSubscriber'
);

$this->assertSame(
$cache = $this->container->get('ivory.http_adapter.default.cache.model'),
$listener->getCache()
);

$this->assertSame($cacheAdapter, $listener->getCache()->getAdapter());
$this->assertTrue($listener->getCache()->cacheException());
}

public function testGlobalCacheSubscriberWithoutException()
{
$this->container->set(
'ivory.cache.adapter',
$cacheAdapter = $this->getMock('Ivory\HttpAdapter\Event\Cache\Adapter\CacheAdapterInterface')
);

$this->loadConfiguration($this->container, 'global_cache_without_exception');
$this->container->compile();

$listener = $this->assertListener(
$this->container->get('ivory.http_adapter.default.event_dispatcher'),
Events::REQUEST_CREATED,
'Ivory\HttpAdapter\Event\Subscriber\CacheSubscriber'
);

$this->assertSame(
$cache = $this->container->get('ivory.http_adapter.default.cache.model'),
$listener->getCache()
);

$this->assertSame($cacheAdapter, $listener->getCache()->getAdapter());
$this->assertFalse($listener->getCache()->cacheException());
}

public function testGlobalCacheSubscriberWithLifetime()
{
$this->container->set(
'ivory.cache.adapter',
$cacheAdapter = $this->getMock('Ivory\HttpAdapter\Event\Cache\Adapter\CacheAdapterInterface')
);

$this->loadConfiguration($this->container, 'global_cache_with_lifetime');
$this->container->compile();

$listener = $this->assertListener(
$this->container->get('ivory.http_adapter.default.event_dispatcher'),
Events::REQUEST_CREATED,
'Ivory\HttpAdapter\Event\Subscriber\CacheSubscriber'
);

$this->assertSame(
$cache = $this->container->get('ivory.http_adapter.default.cache.model'),
$listener->getCache()
);

$this->assertSame($cacheAdapter, $listener->getCache()->getAdapter());
$this->assertSame(100, $listener->getCache()->getLifetime());
}

public function testGlobalCookieSubscriber()
{
$this->container->setParameter('kernel.cache_dir', sys_get_temp_dir());
Expand Down Expand Up @@ -604,6 +679,81 @@ public function testLocalBasicAuthSubscriberWithMatcher()
);
}

public function testLocalCacheSubscriber()
{
$this->container->set(
'ivory.cache.adapter',
$cacheAdapter = $this->getMock('Ivory\HttpAdapter\Event\Cache\Adapter\CacheAdapterInterface')
);

$this->loadConfiguration($this->container, 'local_cache');
$this->container->compile();

$listener = $this->assertListener(
$this->container->get('ivory.http_adapter.local.event_dispatcher'),
Events::REQUEST_CREATED,
'Ivory\HttpAdapter\Event\Subscriber\CacheSubscriber'
);

$this->assertSame(
$cache = $this->container->get('ivory.http_adapter.local.cache.model'),
$listener->getCache()
);

$this->assertSame($cacheAdapter, $listener->getCache()->getAdapter());
$this->assertTrue($listener->getCache()->cacheException());
}

public function testLocalCacheSubscriberWithoutException()
{
$this->container->set(
'ivory.cache.adapter',
$cacheAdapter = $this->getMock('Ivory\HttpAdapter\Event\Cache\Adapter\CacheAdapterInterface')
);

$this->loadConfiguration($this->container, 'local_cache_without_exception');
$this->container->compile();

$listener = $this->assertListener(
$this->container->get('ivory.http_adapter.local.event_dispatcher'),
Events::REQUEST_CREATED,
'Ivory\HttpAdapter\Event\Subscriber\CacheSubscriber'
);

$this->assertSame(
$cache = $this->container->get('ivory.http_adapter.local.cache.model'),
$listener->getCache()
);

$this->assertSame($cacheAdapter, $listener->getCache()->getAdapter());
$this->assertFalse($listener->getCache()->cacheException());
}

public function testLocalCacheSubscriberWithLifetime()
{
$this->container->set(
'ivory.cache.adapter',
$cacheAdapter = $this->getMock('Ivory\HttpAdapter\Event\Cache\Adapter\CacheAdapterInterface')
);

$this->loadConfiguration($this->container, 'local_cache_with_lifetime');
$this->container->compile();

$listener = $this->assertListener(
$this->container->get('ivory.http_adapter.local.event_dispatcher'),
Events::REQUEST_CREATED,
'Ivory\HttpAdapter\Event\Subscriber\CacheSubscriber'
);

$this->assertSame(
$cache = $this->container->get('ivory.http_adapter.local.cache.model'),
$listener->getCache()
);

$this->assertSame($cacheAdapter, $listener->getCache()->getAdapter());
$this->assertSame(100, $listener->getCache()->getLifetime());
}

public function testLocalCookieSubscriber()
{
$this->container->setParameter('kernel.cache_dir', sys_get_temp_dir());
Expand Down
4 changes: 4 additions & 0 deletions Tests/Fixtures/config/Yaml/global_cache.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ivory_http_adapter:
subscribers:
cache:
adapter: ivory.cache.adapter
5 changes: 5 additions & 0 deletions Tests/Fixtures/config/Yaml/global_cache_with_lifetime.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ivory_http_adapter:
subscribers:
cache:
adapter: ivory.cache.adapter
lifetime: 100
5 changes: 5 additions & 0 deletions Tests/Fixtures/config/Yaml/global_cache_without_exception.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ivory_http_adapter:
subscribers:
cache:
adapter: ivory.cache.adapter
exception: false
9 changes: 9 additions & 0 deletions Tests/Fixtures/config/Yaml/local_cache.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ivory_http_adapter:
adapters:
global:
type: socket
local:
type: socket
subscribers:
cache:
adapter: ivory.cache.adapter
10 changes: 10 additions & 0 deletions Tests/Fixtures/config/Yaml/local_cache_with_lifetime.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
ivory_http_adapter:
adapters:
global:
type: socket
local:
type: socket
subscribers:
cache:
adapter: ivory.cache.adapter
lifetime: 100
10 changes: 10 additions & 0 deletions Tests/Fixtures/config/Yaml/local_cache_without_exception.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
ivory_http_adapter:
adapters:
global:
type: socket
local:
type: socket
subscribers:
cache:
adapter: ivory.cache.adapter
exception: false
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
],
"require": {
"php": ">=5.4.8",
"egeloen/http-adapter": "^0.8",
"egeloen/http-adapter": "^0.8@dev",
"symfony/framework-bundle": "^2.2"
},
"require-dev": {
Expand Down

0 comments on commit 8a98333

Please sign in to comment.