From 25fd599c5d8f75856d5d84dbb501dc235ba4e9d2 Mon Sep 17 00:00:00 2001 From: kafkiansky Date: Wed, 25 Mar 2026 10:03:29 +0300 Subject: [PATCH 1/3] Allow to set memory_limit in plugin --- README.md | 28 +++++++++++++ bin/compiler.php | 11 +++++ tests/CompilerMemoryLimitTest.php | 67 +++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 tests/CompilerMemoryLimitTest.php diff --git a/README.md b/README.md index 5998c6a..3ebe225 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ For this reason, we have written this plugin, which — in addition to addressin - [php_namespace](#php_namespace) - [src_path](#src_path) - [grpc](#grpc) + - [memory limit](#memory-limit) - [multiple options](#multiple-options) - [Generated code guide](#generated-code-guide) - [numbers](#numbers) @@ -117,6 +118,7 @@ docker run --rm \ The image behaves exactly like the `protoc` binary — all the same options and flags apply. The `--user` flag ensures that generated files are owned by the current host user rather than root. Replace `0.1.10` with the desired version, or use `latest` to always pull the most recent release. +If needed, you can pass environment variables to the plugin with `-e`, for example: `-e THESIS_PLUGIN_MEMORY_LIMIT=1G`. ### Plugin options @@ -170,6 +172,32 @@ protoc \ To generate only the server code, use `grpc=server`. By default, and when passing `grpc=client,grpc=server`, both the client and server will be generated. +### `memory limit` + +When processing very large schemas, the default PHP `memory_limit` (often `128M`) may be insufficient and lead to plugin exit code `255`. + +The plugin now ensures at least `512M` by default. If you need a different value, override it with the `THESIS_PLUGIN_MEMORY_LIMIT` environment variable. + +When using a locally installed plugin (`phar`/binary): +```shell +THESIS_PLUGIN_MEMORY_LIMIT=1G protoc \ + --plugin=protoc-gen-php-plugin=/usr/local/bin/protoc-gen-php \ + protos/*.proto \ + --php-plugin_out=genproto +``` + +When using the Docker image: +```shell +docker run --rm \ + --user $(id -u):$(id -g) \ + -e THESIS_PLUGIN_MEMORY_LIMIT=1G \ + -v "$(PWD):/workspace" \ + -w /workspace \ + ghcr.io/thesis-php/protoc-plugin:latest \ + --php-plugin_out=genproto \ + protos/*.proto +``` + ### Multiple options You can pass multiple options separated by commas. For example, if you want to specify a different namespace, place all the code in the root directory, and generate only the `gRPC` client, you can write the following: diff --git a/bin/compiler.php b/bin/compiler.php index 325669e..febf52a 100755 --- a/bin/compiler.php +++ b/bin/compiler.php @@ -5,6 +5,17 @@ require_once __DIR__ . '/../vendor/autoload.php'; +if (is_string($configuredMemoryLimit = getenv('THESIS_PLUGIN_MEMORY_LIMIT'))) { + @ini_set('memory_limit', $configuredMemoryLimit); +} else { + $memoryLimitBytes = ini_parse_quantity(ini_get('memory_limit')); + + // We should increase memory_limit if it is lower than 512M. + if ($memoryLimitBytes !== -1 && $memoryLimitBytes < 512 * 1_024 * 1_024) { + @ini_set('memory_limit', '512M'); + } +} + use Thesis\Protobuf\Decoder; use Thesis\Protobuf\Encoder; use Thesis\Protoc; diff --git a/tests/CompilerMemoryLimitTest.php b/tests/CompilerMemoryLimitTest.php new file mode 100644 index 0000000..4f280e7 --- /dev/null +++ b/tests/CompilerMemoryLimitTest.php @@ -0,0 +1,67 @@ + ['file', '/dev/null', 'r'], + 1 => ['file', '/dev/null', 'w'], + 2 => ['pipe', 'w'], + ], + $pipes, + \dirname(__DIR__), + $envMemoryLimit !== null + ? ['THESIS_PLUGIN_MEMORY_LIMIT' => $envMemoryLimit] + : [], + ); + + self::assertIsResource($process); + self::assertArrayHasKey(2, $pipes); + + $stderr = stream_get_contents($pipes[2]); + fclose($pipes[2]); + self::assertIsString($stderr); + + self::assertSame(0, proc_close($process), $stderr); + + self::assertMatchesRegularExpression('/MEMORY_LIMIT=(.+)\n/', $stderr); + preg_match('/MEMORY_LIMIT=(.+)\n/', $stderr, $matches); + + return trim($matches[1] ?? ''); + } +} From d49d9f6f390a44ebd1e2f98ae7253139164ffc53 Mon Sep 17 00:00:00 2001 From: kafkiansky Date: Wed, 25 Mar 2026 10:05:55 +0300 Subject: [PATCH 2/3] chore: remove readme duplication --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 3ebe225..4cde9fc 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,6 @@ docker run --rm \ The image behaves exactly like the `protoc` binary — all the same options and flags apply. The `--user` flag ensures that generated files are owned by the current host user rather than root. Replace `0.1.10` with the desired version, or use `latest` to always pull the most recent release. -If needed, you can pass environment variables to the plugin with `-e`, for example: `-e THESIS_PLUGIN_MEMORY_LIMIT=1G`. ### Plugin options From bcf499c5d236f2538847342763c3bc6bd726b125 Mon Sep 17 00:00:00 2001 From: kafkiansky Date: Wed, 25 Mar 2026 10:08:36 +0300 Subject: [PATCH 3/3] chore: fix readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4cde9fc..079b0f8 100644 --- a/README.md +++ b/README.md @@ -177,7 +177,7 @@ When processing very large schemas, the default PHP `memory_limit` (often `128M` The plugin now ensures at least `512M` by default. If you need a different value, override it with the `THESIS_PLUGIN_MEMORY_LIMIT` environment variable. -When using a locally installed plugin (`phar`/binary): +When using a locally installed plugin: ```shell THESIS_PLUGIN_MEMORY_LIMIT=1G protoc \ --plugin=protoc-gen-php-plugin=/usr/local/bin/protoc-gen-php \