diff --git a/index.js b/index.js index 4bca0796f..072547d74 100644 --- a/index.js +++ b/index.js @@ -88,9 +88,25 @@ class ServerlessPlugin { if (f.runtime === 'provided') { throw new this.serverless.classes.Error(`Bref 1.0 layers are not compatible with the "provided" runtime.\nTo upgrade to Bref 1.0, you have to switch to "provided.al2" in serverless.yml for the function "${name}".\nMore details here: https://bref.sh/docs/news/01-bref-1.0.html#amazon-linux-2`); } + + this.defineBrefFpmTimeout(name) } } + defineBrefFpmTimeout(name) { + const timeout = this.serverless.service.functions[name].timeout ?? + this.serverless.service.provider?.environment?.timeout ?? + 29 // We assume API Gateway Limit. + + const environment = this.serverless.service.functions[name].environment ?? {} + + // Here we subtract one second so that FPM can timeout before lambda crashes + // That will give the Lambda execution enough time to flush out logs. + environment.BREF_FPM_TIMEOUT = (timeout - 1) * 1000 + + this.serverless.service.functions[name].environment = environment; + } + addCustomIamRoleForVendorArchiveDownload() { this.serverless.service.custom = this.serverless.service.custom ? this.serverless.service.custom : {}; this.serverless.service.custom.bref = this.serverless.service.custom.bref ? this.serverless.service.custom.bref : {}; diff --git a/runtime/layers/fpm/bootstrap b/runtime/layers/fpm/bootstrap index 78a1a9b22..648586d08 100755 --- a/runtime/layers/fpm/bootstrap +++ b/runtime/layers/fpm/bootstrap @@ -32,7 +32,12 @@ if (! is_file($handlerFile)) { $lambdaRuntime->failInitialization("Handler `$handlerFile` doesn't exist"); } +$timeout = getenv('BREF_FPM_TIMEOUT'); + $phpFpm = new FpmHandler($handlerFile); + +$phpFpm->setTimeout((int) $timeout); + try { $phpFpm->start(); } catch (\Throwable $e) { diff --git a/src/Event/Http/FpmHandler.php b/src/Event/Http/FpmHandler.php index d31783bbd..99bfb0f9b 100644 --- a/src/Event/Http/FpmHandler.php +++ b/src/Event/Http/FpmHandler.php @@ -48,6 +48,8 @@ final class FpmHandler extends HttpHandler private $configFile; /** @var Process|null */ private $fpm; + /** @var int */ + private $timeout = 900000; public function __construct(string $handler, string $configFile = self::CONFIG) { @@ -55,6 +57,11 @@ public function __construct(string $handler, string $configFile = self::CONFIG) $this->configFile = $configFile; } + public function setTimeout(int $timeout) + { + $this->timeout = $timeout; + } + /** * Start the PHP-FPM process. */ @@ -83,7 +90,7 @@ public function start(): void }); $this->client = new Client; - $this->connection = new UnixDomainSocket(self::SOCKET, 1000, 900000); + $this->connection = new UnixDomainSocket(self::SOCKET, 1000, $this->timeout); $this->waitUntilReady(); }