Skip to content

Commit

Permalink
Fix: cache client problem
Browse files Browse the repository at this point in the history
  • Loading branch information
Stéphane Reuille committed Jul 30, 2015
1 parent 14a82b6 commit 4dbc29a
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 34 deletions.
54 changes: 43 additions & 11 deletions src/DependencyInjection/M6WebGuzzleHttpExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,12 @@ protected function loadClient(ContainerBuilder $container, $clientId, array $con
}
unset($config['redirects']);

$this->setGuzzleProxyHandler($container, $clientId, $config);

$handlerStackDefinition = new Definition('%m6web_guzzlehttp.guzzle.handlerstack.class%');
$handlerStackDefinition->setFactory(['%m6web_guzzlehttp.guzzle.handlerstack.class%', 'create']);
$handlerStackDefinition->setArguments([new Reference('m6web_guzzlehttp.guzzle.proxyhandler')]);
$handlerStackDefinition->setArguments([new Reference('m6web_guzzlehttp.guzzle.proxyhandler_'.$clientId)]);

$container->setDefinition('m6web_guzzlehttp.guzzle.handlerstack.'.$clientId, $handlerStackDefinition);

$handlerStackReference = new Reference('m6web_guzzlehttp.guzzle.handlerstack.'.$clientId);
Expand All @@ -68,17 +71,7 @@ protected function loadClient(ContainerBuilder $container, $clientId, array $con
$config['curl'] = $this->getCurlConfig($config);
}

if (array_key_exists('guzzlehttp_cache', $config)) {
$defaultTtl = $config['guzzlehttp_cache']['default_ttl'];
$headerTtl = $config['guzzlehttp_cache']['use_header_ttl'];
$cacheService = new Reference($config['guzzlehttp_cache']['service']);

$curlHandler = $container->getDefinition('m6web_guzlehttp.handler.curlhandler');
$curlMultiHandler = $container->getDefinition('m6web_guzlehttp.handler.curlmultihandler');

$curlHandler->addMethodCall('setCache', [$cacheService, $defaultTtl, $headerTtl]);
$curlMultiHandler->addMethodCall('setCache', [$cacheService, $defaultTtl, $headerTtl]);
}


$guzzleClientDefintion = new Definition('%m6web_guzzlehttp.guzzle.client.class%');
Expand All @@ -90,6 +83,45 @@ protected function loadClient(ContainerBuilder $container, $clientId, array $con

}

/**
* Set proxy handler definition for the client
*
* @param ContainerBuilder $container
* @param string $clientId
* @param array $config
*/
protected function setGuzzleProxyHandler(ContainerBuilder $container, $clientId, array $config)
{
$handlerFactorySync = new Definition('%m6web_guzlehttp.handler.curlfactory.class%');
$handlerFactorySync->setArguments([3]);

$handlerFactoryNormal = new Definition('%m6web_guzlehttp.handler.curlfactory.class%');
$handlerFactoryNormal->setArguments([50]);

$curlhandler = new Definition('%m6web_guzlehttp.handler.curlhandler.class%');
$curlhandler->setArguments([ ['handle_factory' => $handlerFactorySync] ]);
$curlhandler->addMethodCall('setDebug', [$container->getParameter('kernel.debug')]);

$curlMultihandler = new Definition('%m6web_guzlehttp.handler.curlmultihandler.class%');
$curlMultihandler->setArguments([ ['handle_factory' => $handlerFactoryNormal] ]);
$curlMultihandler->addMethodCall('setDebug', [$container->getParameter('kernel.debug')]);

if (array_key_exists('guzzlehttp_cache', $config)) {
$defaultTtl = $config['guzzlehttp_cache']['default_ttl'];
$headerTtl = $config['guzzlehttp_cache']['use_header_ttl'];
$cacheService = new Reference($config['guzzlehttp_cache']['service']);

$curlhandler->addMethodCall('setCache', [$cacheService, $defaultTtl, $headerTtl]);
$curlMultihandler->addMethodCall('setCache', [$cacheService, $defaultTtl, $headerTtl]);
}

$proxyHandler = new Definition('%m6web_guzzlehttp.guzzle.proxyhandler.class%');
$proxyHandler->setFactory(['%m6web_guzzlehttp.guzzle.proxyhandler.class%', 'wrapSync']);
$proxyHandler->setArguments([$curlMultihandler, $curlhandler]);

$container->setDefinition('m6web_guzzlehttp.guzzle.proxyhandler_'.$clientId, $proxyHandler);
}

protected function getCurlConfig(array $config)
{
$followLocation = (!empty($config['allow_redirects']));
Expand Down
23 changes: 0 additions & 23 deletions src/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,5 @@ parameters:
m6web_guzzlehttp.middleware.eventdispatcher.class: M6Web\Bundle\GuzzleHttpBundle\Middleware\EventDispatcherMiddleware

services:
m6web_guzlehttp.handler.curlfactory.sync:
class: %m6web_guzlehttp.handler.curlfactory.class%
arguments: [3]

m6web_guzlehttp.handler.curlfactory.normal:
class: %m6web_guzlehttp.handler.curlfactory.class%
arguments: [50]

m6web_guzlehttp.handler.curlhandler:
class: %m6web_guzlehttp.handler.curlhandler.class%
arguments: [ {handle_factory: "@m6web_guzlehttp.handler.curlfactory.sync"} ]
calls: [ ['setDebug', [%kernel.debug%]] ]

m6web_guzlehttp.handler.curlmultihandler:
class: %m6web_guzlehttp.handler.curlmultihandler.class%
arguments: [ {handle_factory : "@m6web_guzlehttp.handler.curlfactory.normal"} ]
calls: [ ['setDebug', [%kernel.debug%]] ]

m6web_guzzlehttp.guzzle.proxyhandler:
class: %m6web_guzzlehttp.guzzle.proxyhandler.class%
factory: [%m6web_guzzlehttp.guzzle.proxyhandler.class%, wrapSync]
arguments:
- "@m6web_guzlehttp.handler.curlmultihandler"
- "@m6web_guzlehttp.handler.curlhandler"

14 changes: 14 additions & 0 deletions tests/Fixtures/cache-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
m6web_guzzlehttp:
clients:
default:
base_uri: "http://domain.tld"
guzzlehttp_cache:
default_ttl: 100
use_header_ttl: false
service: cache_service
myclient:
base_uri: "http://domain2.tld"
guzzlehttp_cache:
default_ttl: 300
use_header_ttl: true
service: cache_service2
94 changes: 94 additions & 0 deletions tests/Units/DependencyInjection/M6WebGuzzleHttpExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use GuzzleHttp\Promise;
use M6Web\Bundle\GuzzleHttpBundle\DependencyInjection\M6WebGuzzleHttpExtension as TestedClass;
use GuzzleHttp\Psr7\Response;

class M6WebGuzzleHttpExtension extends test
{
Expand Down Expand Up @@ -129,6 +130,46 @@ public function testMulticlientConfig()
;
}

public function testCacheConfig()
{
$mockCache = new \mock\M6Web\Bundle\GuzzleHttpBundle\Cache\CacheInterface();
$mockCache2 = new \mock\M6Web\Bundle\GuzzleHttpBundle\Cache\CacheInterface();

$container = $this->getContainerForConfiguation('cache-config');
$container->set('cache_service', $mockCache);
$container->set('cache_service2', $mockCache2);
$container->compile();

$this
->boolean($container->has('m6web_guzzlehttp'))
->isTrue()
->array($arguments = $container->getDefinition('m6web_guzzlehttp')->getArgument(0))
->hasSize(9)
->array($cacheConfig = $arguments['guzzlehttp_cache'])
->hasSize(3)
->integer($cacheConfig['default_ttl'])
->isEqualTo(100)
->boolean($cacheConfig['use_header_ttl'])
->isFalse()
->string($cacheConfig['service'])
->isEqualTo('cache_service')

->boolean($container->has('m6web_guzzlehttp_myclient'))
->isTrue()
->array($arguments = $container->getDefinition('m6web_guzzlehttp_myclient')->getArgument(0))
->hasSize(9)
->array($cacheConfig = $arguments['guzzlehttp_cache'])
->hasSize(3)
->integer($cacheConfig['default_ttl'])
->isEqualTo(300)
->boolean($cacheConfig['use_header_ttl'])
->isTrue()
->string($cacheConfig['service'])
->isEqualTo('cache_service2')
;

}

public function testClientConfiguration()
{
$container = $this->getContainerForConfiguation('default-config');
Expand Down Expand Up @@ -186,13 +227,66 @@ public function testEventDispatcherMulticlient()
;
}

public function testMulticlientCache()
{
$mockCache = new \mock\M6Web\Bundle\GuzzleHttpBundle\Cache\CacheInterface();
$mockCache2 = new \mock\M6Web\Bundle\GuzzleHttpBundle\Cache\CacheInterface();

$container = $this->getContainerForConfiguation('cache-config');
$container->set('cache_service', $mockCache);
$container->set('cache_service2', $mockCache2);
$container->compile();

$this
->if($client = $container->get('m6web_guzzlehttp'))
->and($client2 = $container->get('m6web_guzzlehttp_myclient'))
->and($response = $client->get('http://httpbin.org/robots.txt'))
->and($response2 = $client->get('http://httpbin.org/cache/10'))
->then
->mock($mockCache)
->call('set')
->withArguments(md5('http://httpbin.org/robots.txt'), $this->getSerializedResponse($response), 100)
->once()
->withArguments(md5('http://httpbin.org/cache/10'), $this->getSerializedResponse($response2), 100)
->once()
->withAnyArguments()
->twice()
->if($response = $client2->get('http://httpbin.org'))
->and($response2 = $client2->get('http://httpbin.org/cache/10'))
->then
->mock($mockCache2)
->call('set')
->withArguments(md5('http://httpbin.org'), $this->getSerializedResponse($response), 300)
->once()
->withArguments(md5('http://httpbin.org/cache/10'), $this->getSerializedResponse($response2), 10)
->once()
->withAnyArguments()
->twice()
;

}

protected function getSerializedResponse(Response $response)
{
$cached = new \SplFixedArray(5);
$cached[0] = $response->getStatusCode();
$cached[1] = $response->getHeaders();
$cached[2] = $response->getBody()->__toString();
$cached[3] = $response->getProtocolVersion();
$cached[4] = $response->getReasonPhrase();

return serialize($cached);
}

protected function getContainerForConfiguation($fixtureName)
{
$extension = new TestedClass();

$parameterBag = new ParameterBag(array('kernel.debug' => true));
$container = new ContainerBuilder($parameterBag);
$container->set('event_dispatcher', new \mock\Symfony\Component\EventDispatcher\EventDispatcherInterface());
$container->set('cache_service', new \mock\M6Web\Bundle\GuzzleHttpBundle\Cache\CacheInterface());
$container->set('cache_service2', new \mock\M6Web\Bundle\GuzzleHttpBundle\Cache\CacheInterface());
$container->registerExtension($extension);

$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../../Fixtures/'));
Expand Down

0 comments on commit 4dbc29a

Please sign in to comment.