php-docs-samples icon indicating copy to clipboard operation
php-docs-samples copied to clipboard

RFC: feat(functions): PHP 7.4 preloading

Open bshaffer opened this issue 4 years ago • 6 comments

WIP for preloading in PHP 7.4 Cloud Functions

This demo suggests the users do the following:

  1. Add the following to composer.json

    {
        "config": {
            "optimize-autoloader": true
        },
    }
    
  2. Add a preload.php file containing the following:

    require_once __DIR__ . '/vendor/autoload.php';
    
    // By running "composer dump-autoload --optimize", the classmap file contains a
    // mapping of optimized class files.
    $composerClassmap = __DIR__ . '/vendor/composer/autoload_classmap.php';
    
    $classesToPreload = require $composerClassmap;
    
    foreach ($classesToPreload as $class => $file) {
        require_once $file;
    }
    
  3. Add a php.ini containing the following:

    opcache.preload=preload.php
    

And that's it! Preloading will work for any/all classes handled by Composer's autoloader

bshaffer avatar Mar 13 '21 00:03 bshaffer

Here is the summary of changes.

You are about to add 1 region tag.

This comment is generated by snippet-bot. If you find problems with this result, please file an issue at: https://github.com/googleapis/repo-automation-bots/issues. To update this comment, add snippet-bot:force-run label or use the checkbox below:

  • [ ] Refresh this comment

snippet-bot[bot] avatar Mar 13 '21 00:03 snippet-bot[bot]

I am was receiving the following error when running the deployment:

PHP Fatal error:  Uncaught Error: Class 'PHPUnit\Framework\TestCase' not found in /workspace/test/IntegrationTest.php:28
Stack trace:
#0 /workspace/preload.php(12): require_once()
#1 {main}
  thrown in /workspace/test/IntegrationTest.php on line 28 

This is very strange, since test/IntegrationTest.php does not show up (locally) when I run the same composer commands. I tried ignoring test/ via .gcloudignore, and the error changed to Failed opening required '/workspace/test/IntegrationTest.php', which isn't any better.

To fix this, I deployed with a new function NAME. I believe the reason is the vendor directory is cached for multiple deployments with the same function name if composer.json has not changed. So this is important to note...

I believe the main fix here is to upgrade the server's version of composer. The newer versions will skip adding classes to the classmap if they do not conform to the autoloading rules inside composer.json, allowing test classes and other dev classes to be deployed to the server without throwing errors like this.

bshaffer avatar Mar 13 '21 01:03 bshaffer

Do we have any data on the benefits? E.g., A/B performance?

grayside avatar Mar 17 '21 20:03 grayside

@grayside no benchmarks, no, but we should definitely do some sanity-checking here. In theory, it should provide significant improvements on all requests, as the entire classmap is loaded into memory before the first request.

bshaffer avatar Mar 17 '21 21:03 bshaffer