Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: feat(functions): PHP 7.4 preloading #1304

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
15 changes: 15 additions & 0 deletions functions/tips_preload/.gcloudignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# The .gcloudignore file excludes file from upload to Cloud Build.
# If this file is deleted, gcloud will default to .gitignore.
#
# https://cloud.google.com/cloud-build/docs/speeding-up-builds#gcloudignore
# https://cloud.google.com/sdk/gcloud/reference/topic/gcloudignore

# Exclude our local tests
test/

# Exclude locally vendored dependencies.
vendor/

# Exclude git history and configuration.
.git/
.gitignore
28 changes: 28 additions & 0 deletions functions/tips_preload/ClassToPreload.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
/**
* Copyright 2021 Google LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace Google\Cloud\Samples\Functions\TipsPreload;

/**
* Empty class to verify the preloading works.
* We use a new class so that we know it won't be preloaded by another class
* before we can check for it in "index.php".
*/
class ClassToPreload
{
// There is nothing to be done
}
19 changes: 19 additions & 0 deletions functions/tips_preload/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"require": {
"google/cloud-functions-framework": "^0.7.2"
},
"config": {
"optimize-autoloader": true
},
"autoload": {
"psr-4": {
"Google\\Cloud\\Samples\\Functions\\TipsPreload\\": ""
}
},
"scripts": {
"start": [
"Composer\\Config::disableProcessTimeout",
"FUNCTION_TARGET=preloadDemo php -d opcache.preload=preload.php -S localhost:${PORT:-8080} vendor/bin/router.php"
]
}
}
33 changes: 33 additions & 0 deletions functions/tips_preload/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php
/**
* Copyright 2021 Google LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// [START functions_tips_preload]

use Psr\Http\Message\ServerRequestInterface;
use Google\Cloud\Samples\Functions\TipsPreload\ClassToPreload;

function preloadDemo(ServerRequestInterface $request = null): string
{
// Verify the class exists without making a call to the autoloader
$classIsPreloaded = class_exists(ClassToPreload::class, $autoload = false);

return sprintf(
'Class is preloaded: %s',
var_export($classIsPreloaded, true)
);
}
// [END functions_tips_preload]
1 change: 1 addition & 0 deletions functions/tips_preload/php.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
opcache.preload=preload.php
34 changes: 34 additions & 0 deletions functions/tips_preload/phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2021 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<phpunit bootstrap="../../testing/bootstrap.php" convertWarningsToExceptions="false">
<testsuites>
<testsuite name="Cloud Functions preload Test Suite">
<directory>test</directory>
</testsuite>
</testsuites>
<logging>
<log type="coverage-clover" target="build/logs/clover.xml"/>
</logging>
<filter>
<whitelist>
<directory suffix=".php">.</directory>
<exclude>
<directory>./vendor</directory>
</exclude>
</whitelist>
</filter>
</phpunit>
13 changes: 13 additions & 0 deletions functions/tips_preload/preload.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

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;
}
52 changes: 52 additions & 0 deletions functions/tips_preload/test/DeployTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php
/**
* Copyright 2021 Google LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

declare(strict_types=1);

namespace Google\Cloud\Samples\Functions\TipsPreload\Test;

use Google\Cloud\TestUtils\CloudFunctionDeploymentTrait;
use PHPUnit\Framework\TestCase;

/**
* Class DeployTest.
*
* This test is not run by the CI system.
*
* To skip deployment of a new function, run with "GOOGLE_SKIP_DEPLOYMENT=true".
* To skip deletion of the tested function, run with "GOOGLE_KEEP_DEPLOYMENT=true".
*/
class DeployTest extends TestCase
{
use CloudFunctionDeploymentTrait;

private static $entryPoint = 'preloadDemo';

public function testFunction(): void
{
// Send a request to the function.
$resp = $this->client->post('', [
// Uncomment and CURLOPT_VERBOSE debug content will be sent to stdout.
// 'debug' => true
]);

$output = trim((string) $resp->getBody());

$this->assertEquals('200', $resp->getStatusCode());
$this->assertStringContainsString('Class is preloaded: true', $output);
}
}
52 changes: 52 additions & 0 deletions functions/tips_preload/test/IntegrationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php
/**
* Copyright 2021 Google LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare(strict_types=1);

namespace Google\Cloud\Samples\Functions\TipsPreload\Test;

use Google\Cloud\TestUtils\CloudFunctionLocalTestTrait;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\PhpExecutableFinder;

/**
* Class IntegrationTest.
*/
class IntegrationTest extends TestCase
{
use CloudFunctionLocalTestTrait;

private static $entryPoint = 'preloadDemo';

public function testFunction(): void
{
$resp = $this->client->get('/');
$output = trim((string) $resp->getBody());

$this->assertEquals('200', $resp->getStatusCode());
$this->assertStringContainsString('Class is preloaded: true', $output);
}

private static function doRun()
{
$phpBin = (new PhpExecutableFinder())->find();

// add opcache.preload ini
$phpBin .= ' -d opcache.preload=preload.php';

return self::$fn->run([], '8080', $phpBin);
}
}