Bladeren bron

[FrameworkBundle] added a cache warmer for the router

To enable this cache warmer, you must add a "cache-warner" option
to app:router:

        <app:config>
            <app:router cache-warmer="true" />
Fabien Potencier 14 jaren geleden
bovenliggende
commit
edb11ad5cb

+ 10 - 3
src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

@@ -465,15 +465,22 @@ class FrameworkExtension extends Extension
 
         $container->setParameter('routing.resource', $config['router']['resource']);
 
+        if (isset($config['router']['cache-warmer'])) {
+            $config['router']['cache_warmer'] = $config['router']['cache-warmer'];
+        }
+
+        if (isset($config['router']['cache_warmer']) && $config['router']['cache_warmer']) {
+            $container->getDefinition('router.cache_warmer')->addTag('kernel.cache_warmer');
+            $container->setAlias('router', 'router.cached');
+        }
+
         $this->addClassesToCompile(array(
             'Symfony\\Component\\Routing\\RouterInterface',
-            'Symfony\\Component\\Routing\\Router',
             'Symfony\\Component\\Routing\\Matcher\\UrlMatcherInterface',
             'Symfony\\Component\\Routing\\Matcher\\UrlMatcher',
             'Symfony\\Component\\Routing\\Generator\\UrlGeneratorInterface',
             'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
-            'Symfony\\Component\\Routing\\Loader\\LoaderInterface',
-            'Symfony\\Bundle\\FrameworkBundle\\Routing\\LazyLoader',
+            $container->findDefinition('router')->getClass()
         ));
     }
 

+ 16 - 1
src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml

@@ -6,6 +6,7 @@
 
     <parameters>
         <parameter key="router.class">Symfony\Component\Routing\Router</parameter>
+        <parameter key="router.cached.class">Symfony\Bundle\FrameworkBundle\Routing\CachedRouter</parameter>
         <parameter key="routing.loader.class">Symfony\Bundle\FrameworkBundle\Routing\DelegatingLoader</parameter>
         <parameter key="routing.file_locator.class">Symfony\Bundle\FrameworkBundle\Routing\FileLocator</parameter>
         <parameter key="routing.resolver.class">Symfony\Component\Routing\Loader\LoaderResolver</parameter>
@@ -18,6 +19,7 @@
         <parameter key="router.options.matcher_class">Symfony\Component\Routing\Matcher\UrlMatcher</parameter>
         <parameter key="router.options.matcher_base_class">Symfony\Component\Routing\Matcher\UrlMatcher</parameter>
         <parameter key="router.options.matcher_dumper_class">Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper</parameter>
+        <parameter key="router.cache_warmer.class">Symfony\Bundle\FrameworkBundle\Routing\CacheWarmer\RouterCacheWarmer</parameter>
     </parameters>
 
     <services>
@@ -53,7 +55,7 @@
             <argument>routing.loader.real</argument>
         </service>
 
-        <service id="router" class="%router.class%">
+        <service id="router.real" class="%router.class%">
             <argument type="service" id="routing.loader" />
             <argument>%routing.resource%</argument>
             <argument type="collection">
@@ -69,5 +71,18 @@
                 <argument key="matcher_cache_class">%kernel.name%_%kernel.environment%UrlMatcher</argument>
             </argument>
         </service>
+
+        <service id="router" alias="router.real" />
+
+        <service id="router.cached" class="%router.cached.class%">
+            <argument>%kernel.cache_dir%</argument>
+            <argument key="matcher_cache_class">%kernel.name%_%kernel.environment%UrlMatcher</argument>
+            <argument key="generator_cache_class">%kernel.name%_%kernel.environment%UrlGenerator</argument>
+        </service>
+
+        <service id="router.cache_warmer" class="%router.cache_warmer.class%" public="false">
+            <tag name="kernel.cache_warmer" />
+            <argument type="service" id="router.real" />
+        </service>
     </services>
 </container>

+ 1 - 0
src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd

@@ -49,6 +49,7 @@
     <xsd:complexType name="router">
         <xsd:attribute name="resource" type="xsd:string" />
         <xsd:attribute name="type" type="xsd:string" />
+        <xsd:attribute name="cache-warmer" type="cache_warmer" />
     </xsd:complexType>
 
     <xsd:complexType name="validation">

+ 57 - 0
src/Symfony/Bundle/FrameworkBundle/Routing/CacheWarmer/RouterCacheWarmer.php

@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\FrameworkBundle\Routing\CacheWarmer;
+
+use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmer;
+use Symfony\Component\Routing\Router;
+
+/**
+ * Generates the router matcher and generator classes.
+ *
+ * @author Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class RouterCacheWarmer extends CacheWarmer
+{
+    protected $router;
+
+    /**
+     * Constructor.
+     *
+     * @param router $router A Router instance
+     */
+    public function __construct(Router $router)
+    {
+        $this->router = $router;
+    }
+
+    /**
+     * Warms up the cache.
+     *
+     * @param string $cacheDir The cache directory
+     */
+    public function warmUp($cacheDir)
+    {
+        // force cache generation
+        $this->router->getMatcher();
+        $this->router->getGenerator();
+    }
+
+    /**
+     * Checks whether this warmer is optional or not.
+     *
+     * @return Boolean always false
+     */
+    public function isOptional()
+    {
+        return false;
+    }
+}

+ 89 - 0
src/Symfony/Bundle/FrameworkBundle/Routing/CachedRouter.php

@@ -0,0 +1,89 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\FrameworkBundle\Routing;
+
+use Symfony\Component\Routing\RouterInterface;
+
+/**
+ * This Router is optimized to work with matcher and generator classes
+ * generated in the cache.
+ *
+ * @author Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class CachedRouter implements RouterInterface
+{
+    protected $matcher;
+    protected $generator;
+
+    /**
+     * Constructor.
+     *
+     * @param string $cacheDir  The cache directory
+     * @param string $matcher   The matcher class name
+     * @param string $generator The generator class name
+     * @param array  $context   The context
+     * @param array  $defaults  The default values
+     */
+    public function __construct($cacheDir, $matcher, $generator, array $context = array(), array $defaults = array())
+    {
+        if (!file_exists($cache = $cacheDir.'/'.$matcher.'.php')) {
+            throw new \RuntimeException(sprintf('The routing cache is not warmed up (%s).', $cache));
+        }
+
+        if (!class_exists($matcher)) {
+            require_once $cache;
+            require_once $cacheDir.'/'.$generator.'.php';
+        }
+
+        $this->matcher = new $matcher($context, $defaults);
+        $this->generator = new $generator($context, $defaults);
+    }
+
+    /**
+     * Sets the request context.
+     *
+     * @param array $context  The context
+     */
+    public function setContext(array $context = array())
+    {
+        $this->matcher->setContext($context);
+        $this->generator->setContext($context);
+    }
+
+    /**
+     * Generates a URL from the given parameters.
+     *
+     * @param  string  $name       The name of the route
+     * @param  array   $parameters An array of parameters
+     * @param  Boolean $absolute   Whether to generate an absolute URL
+     *
+     * @return string The generated URL
+     */
+    public function generate($name, array $parameters = array(), $absolute = false)
+    {
+        return $this->generator->generate($name, $parameters, $absolute);
+    }
+
+    /**
+     * Tries to match a URL with a set of routes.
+     *
+     * Returns false if no route matches the URL.
+     *
+     * @param  string $url URL to be parsed
+     *
+     * @return array|false An array of parameters or false if no route matches
+     */
+    public function match($url)
+    {
+        return $this->matcher->match($url);
+    }
+}