Skip to content

THRIFT-5984: Cache function_exists() capability checks in PHP runtime#3464

Merged
sveneld merged 1 commit into
apache:masterfrom
sveneld:THRIFT-5984
May 12, 2026
Merged

THRIFT-5984: Cache function_exists() capability checks in PHP runtime#3464
sveneld merged 1 commit into
apache:masterfrom
sveneld:THRIFT-5984

Conversation

@sveneld
Copy link
Copy Markdown
Contributor

@sveneld sveneld commented May 12, 2026

Memoize PHP capability probes that previously ran on every hot call.

Changes:

  • TBinarySerializer::serialize / deserializefunction_exists('thrift_protocol_{write,read}_binary') was called on every invocation. Now cached via static ?bool flags + hasAcceleratedWrite() / hasAcceleratedRead() helpers using the null-coalescing assignment (??=) operator.
  • TSocket::openfunction_exists() was called twice per open() to detect the sockets extension. Cached via hasSocketsExtension() helper.
  • TSocketPool — replaces per-instance $useApcuCache property with static $hasApcuCache + hasApcuCache() helper for consistency. APCu availability is a process-level property, not per-pool.

Each helper performs the check at most once per PHP process. Pure optimization — no behavior change.

Tests:

  • Reset the static caches in setUp() of TBinarySerializerTest, TSocketTest, TSocketPoolTest via reflection so the mocked function_exists is re-evaluated per test method (otherwise the cache would persist across tests in a single PHPUnit process).
  • Register lib/php/src/ext/thrift_protocol/php_thrift_protocol.stub.php in phpstan.neon scanFiles so PHPStan knows about the C-extension functions guarded by the new helpers — previously the inline function_exists() gave PHPStan a narrowing hint that the helper now hides.

Validation (Docker thrift-php-dev:local):

  • phpcs — 0 errors
  • phpstan (level 1) — 0 errors
  • phpunit Unit Suite — 635 tests, 0 failures
  • phpunit Integration Suite — 108 tests, 0 failures

Part of the umbrella ticket THRIFT-5960 (PHP modernization).

  • Did you create an Apache Jira ticket? — THRIFT-5984
  • PR title follows the pattern "THRIFT-NNNN: describe my issue"
  • Squashed to a single commit
  • No breaking changes (TSocketPool::$useApcuCache was private)

Generated-by: Claude Opus 4.7

Client: php

Memoize PHP capability probes that previously ran on every hot call:

- TBinarySerializer::serialize / deserialize — previously called
  function_exists('thrift_protocol_{write,read}_binary') on every
  invocation. Now cached via static nullable bool flags +
  hasAcceleratedWrite() / hasAcceleratedRead() helpers using the
  null-coalescing assignment (??=) operator.

- TSocket::open — previously called function_exists() twice per
  open() to detect the sockets extension. Cached via
  hasSocketsExtension() helper.

- TSocketPool — replace per-instance $useApcuCache property with
  static $hasApcuCache + hasApcuCache() helper for consistency with
  the rest of the cleanup. APCu availability is a process-level
  property, not per-pool.

Each helper performs the check at most once per PHP process. Pure
optimization — no behavior change.

Tests:
- Add cache resets in setUp() of TBinarySerializerTest, TSocketTest,
  TSocketPoolTest via reflection so mocked function_exists is
  re-evaluated per test method.
- Register lib/php/src/ext/thrift_protocol/php_thrift_protocol.stub.php
  in phpstan.neon scanFiles so PHPStan knows about the C-extension
  functions guarded by the new helpers (previously the inline
  function_exists() gave PHPStan a narrowing hint that the helper
  hides).

Part of the umbrella ticket THRIFT-5960 (PHP modernization).

Generated-by: Claude Opus 4.7
@sveneld sveneld marked this pull request as ready for review May 12, 2026 18:27
@sveneld sveneld merged commit cc66145 into apache:master May 12, 2026
93 of 94 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant