Skip to content

fix(buffer): persist off the request path and at shutdown - #33

Merged
rennf93 merged 2 commits into
mainfrom
fix/agent-persist-off-request-path
Oct 15, 2026
Merged

rennf93 merged 2 commits into
mainfrom
fix/agent-persist-off-request-path

Conversation

@rennf93

@rennf93 rennf93 commented Oct 15, 2026

Copy link
Copy Markdown
Member

Delivers issue: #32

Closes #32

Description

Moves the Redis persist of buffered events and metrics off the request path (adding an item no longer waits on Redis) and makes sure pending items are written whenever PHP can still run code. persistPending() runs at the end of flushBuffer(), from tick(), and now from a shutdown function (GuardAgent::persistAtShutdown()) registered once when Redis persistence is attached.

Motivation and Context

The write on every add put a Redis round trip, up to the command timeout, on the request path. Deferring it created a window where a request that ends before any flush or tick loses its items. The shutdown function closes that window for normal end, exit(), an uncaught exception, a fatal error, out of memory and max_execution_time. SIGKILL and an unhandled SIGTERM run no PHP code, so they are documented as the only cases that lose events. I did not add a SIGTERM handler (it would override the host's) and do not call fastcgi_finish_request() (it would cut off output and shutdown functions the host registers later).

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation change
  • Performance improvement
  • Code cleanup or refactoring

How Has This Been Tested

bin/test_shutdown.php spawns a child php per termination mode against a real Redis and asserts the key is present afterwards. On e5e72ce the six PHP-runnable modes fail (0 keys), with the fix they pass. SIGKILL and SIGTERM (no handler) leave 0 keys, and SIGTERM with a host pcntl handler that calls exit() persists. bin/test_agent.php (653 checks), the coverage runner (100%), the php -l sweep, composer validate --strict and composer audit all pass locally on PHP 8.5.


Checklist

  • I have added tests to cover my changes
  • All new and existing tests passed
  • My change requires a change to the documentation
  • I have updated the documentation accordingly
  • I have checked that my changes don't introduce any new warnings or errors

A request that ends before any flush or tick (normal end, exit, uncaught exception, fatal error, out of memory, max_execution_time) now writes its pending items to Redis from a shutdown function registered once when persistence is attached. bin/test_shutdown.php proves each case against a real Redis and documents that SIGKILL and an unhandled SIGTERM run no PHP code.
@rennf93 rennf93 added the bug Confirmed defect label Oct 15, 2026
@github-actions github-actions Bot added documentation Docs site, README, governance files area: core Touches the agent lifecycle, config, or buffers area: transport Touches HTTP transport, compression, or payload signing tests Test suite changes ci GitHub Actions workflows labels Oct 15, 2026
@rennf93
rennf93 merged commit 4628bdf into main Oct 15, 2026
16 checks passed
@rennf93
rennf93 deleted the fix/agent-persist-off-request-path branch October 15, 2026 06:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: core Touches the agent lifecycle, config, or buffers area: transport Touches HTTP transport, compression, or payload signing bug Confirmed defect ci GitHub Actions workflows documentation Docs site, README, governance files tests Test suite changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Buffered events are lost when the process ends before a flush or tick

1 participant