Phalcon\Mvc\Micro->mount performance issues

Hey guys

I did some profiling with Xdebug on my Phalcon micro application and found some major issues.

OS: Amazon Linux on Elastic Beanstalk

PHP: 7.1 with OpCache also enabled

Screenshots:

Profiler: https://imgur.com/a/N2qcOgw

Snippet: https://imgur.com/iDaCfDY

Phalcon\Mvc\Micro->mount time used in request is 43% of total requests time (see screenshot)

Phalcon\Mvc\Router->handle time used in request is 15,7% of total requests time (see screenshot) etc...

I have 57 micro collections and 257 routes

The routes is returned from file config/routes.php as an array and is looped in app.php and it automatically creates the routes (see image)

With no route the script execution time is 1-2ms With all 257 routes it is 10-30ms

Do you guys have any suggestions how i can improve performance... ?

Thank you

Most of the time on production result of all mounts could be just cached, and instead of mounting them you could just set handlers. Extend phalcon micro and add such functionallity yourself, simple as that.

For optimizing handle - there is no way around this currently for yourself, well you can always just write new router for phalcon if you want :)

Can you give a simple example?... I'm not quite sure how to just set the handlers...

edited Sep '18
class YourMicro extends Micro
{
    public function setHandlers($handlers)
    {
        $this->_handlers = $handlers;
        return $this;
    }
}

Somewhere in your code:

$micro = new YourMicro();
$cachedHandlers = $di->get('cache')->get('cached_handlers');
if (empty($cachedHandlers)) {
    // do all the mounts here
    $di->get('cache')->save('cached_handlers', $micro->getHandlers(), 0);
} else {
    $micro->setHandlers($cachedHandlers);
}

Not sure why phalcon doesn't provide setter.

edited Sep '18

Getting this error when saving via $app->persistent->handlers = $app->getHandlers();

[04-Sep-2018 19:39:15 Europe/Copenhagen] PHP Fatal error: Uncaught Exception: Serialization of 'Closure' is not allowed in [no active file]

edited Sep '18

Found this thread https://forum.phalconphp.com/discussion/16895/routing-performance-in-micro-app

Describes the same issues as here. And routes can't be cached because of lazy instantiation...

edited Sep '18

Thanks i'll try! I'll circle back when i've tried it

Though this is exactly why i wrote there it might be actually a slow, well i forgot to mention there that i mean caching routers with closuers, that you need to use 3rd party. Atually if you have router without closuers it might be faster. You could eventually try not use lazy and then caching if you don't care about memory.

edited Sep '18

Still says:

05-Sep-2018 13:03:22 Europe/Copenhagen] PHP Fatal error: Uncaught Exception: Serialization of 'Closure' is not allowed in [no active file]:0 Stack trace: 0 [internal function]: session_write_close() 1 [internal function]: Phalcon\Session\Adapter->__destruct() 2 {main} thrown in [no active file] on line 0*

Screenshot

And using https://github.com/jeremeamia/super_closure is way too slow, serializing/deserializing all controllers (has to be a closure)

edited Sep '18

You sure that those controllers doesn't have any closuers somewhere? You need to just find where you have closure in this code and try to refactor it somehow.

Also don't use persistent for this, use cache.

Also i forgot to mention but you also need to use $this->router->getRoutes() and cache them as well since mount is also adding route objects.

Caching handlers now work next error i get is:

[05-Sep-2018 21:48:02 Europe/Copenhagen] PHP Fatal error: Uncaught Phalcon\Mvc\Micro\Exception: Matched route doesn't have an associated handler in /Users/AndreasAagaard/PhpstormProjects/QuickOrder - Api/api/v8/public/index.php:57

So when the routes is cached what do i do in the else: block? Where ->setHandlers is called

screenshot

edited Sep '18

Yea i wrote you above also that you need to cache routes. Handlers are just handlers, routes are routes.