PluginProbe
404 Solution / trunk
404 Solution vtrunk
4.3.5 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 4.2.0 4.1.19 4.1.18 4.1.17 4.1.16 4.1.15 4.1.13 4.1.12 4.1.11 4.1.10 4.1.9 4.1.8 4.1.7 4.1.6 4.1.5 4.1.4 4.1.3 trunk 2.30.0 All 109 releases
404-solution / includes / root-boot / RequestBenchmark.php

RequestBenchmark.php in 404 Solution trunk, at includes/root-boot/RequestBenchmark.php

147 lines 5.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH')) {
3 exit;
4 }
5
6 /**
7 * Per-request benchmark instrumentation for the plugin bootstrap.
8 *
9 * Disabled by default and only enabled when a request carries ?abj404_bench=1.
10 * Tracks bootstrap timing, DB query count/time, and redirect-lookup time in a
11 * request-scoped global, then emits an X-ABJ404-Benchmark response header.
12 *
13 * The executable wiring (abj404_benchmark_bootstrap_start() at boot,
14 * abj404_benchmark_mark_bootstrap_done() after the template_redirect hook is
15 * registered, and the send_headers add_action) stays in 404-solution.php so the
16 * timing markers fire in the correct request lifecycle order. This file only
17 * defines the functions.
18 */
19 // allow-no-test-found: boot-time benchmark instrumentation global functions wired into the request lifecycle in 404-solution.php; no same-named unit file. abj404_is_benchmark_request and the abj404_benchmark_* markers are exercised in CompetitiveBenchmarkAssetsTest.
20
21 if (!function_exists('abj404_is_benchmark_request')) {
22 /**
23 * Benchmark instrumentation is disabled by default and only enabled per-request.
24 *
25 * @return bool
26 */
27 function abj404_is_benchmark_request() {
28 if (!isset($_GET['abj404_bench'])) {
29 return false;
30 }
31 $flag = $_GET['abj404_bench'];
32 return is_scalar($flag) && (string)$flag === '1';
33 }
34 }
35
36 if (!function_exists('abj404_benchmark_state_ref')) {
37 /**
38 * Return a typed reference to the request-scoped benchmark accumulator,
39 * initializing it if necessary. Centralizing the typed shape here keeps the
40 * recorder/emitter functions free of mixed-offset access on the global.
41 *
42 * @return array{start: float, bootstrap_done: float, db_query_count: int, db_query_ms: float, redirect_lookup_ms: float}
43 */
44 function &abj404_benchmark_state_ref() {
45 if (!isset($GLOBALS['abj404_benchmark_state']) || !is_array($GLOBALS['abj404_benchmark_state'])) {
46 $GLOBALS['abj404_benchmark_state'] = array(
47 'start' => abj404_now_float(),
48 'bootstrap_done' => 0.0,
49 'db_query_count' => 0,
50 'db_query_ms' => 0.0,
51 'redirect_lookup_ms' => 0.0,
52 );
53 }
54 $rawState = $GLOBALS['abj404_benchmark_state'];
55 /** @var array<string, mixed> $rawState */
56 $GLOBALS['abj404_benchmark_state'] = array(
57 'start' => isset($rawState['start']) && is_numeric($rawState['start']) ? (float)$rawState['start'] : 0.0,
58 'bootstrap_done' => isset($rawState['bootstrap_done']) && is_numeric($rawState['bootstrap_done']) ? (float)$rawState['bootstrap_done'] : 0.0,
59 'db_query_count' => isset($rawState['db_query_count']) && is_numeric($rawState['db_query_count']) ? (int)$rawState['db_query_count'] : 0,
60 'db_query_ms' => isset($rawState['db_query_ms']) && is_numeric($rawState['db_query_ms']) ? (float)$rawState['db_query_ms'] : 0.0,
61 'redirect_lookup_ms' => isset($rawState['redirect_lookup_ms']) && is_numeric($rawState['redirect_lookup_ms']) ? (float)$rawState['redirect_lookup_ms'] : 0.0,
62 );
63 /** @var array{start: float, bootstrap_done: float, db_query_count: int, db_query_ms: float, redirect_lookup_ms: float} $state */
64 $state = &$GLOBALS['abj404_benchmark_state'];
65 return $state;
66 }
67 }
68
69 if (!function_exists('abj404_benchmark_bootstrap_start')) {
70 /** @return void */
71 function abj404_benchmark_bootstrap_start() {
72 if (!abj404_is_benchmark_request()) {
73 return;
74 }
75 // Initialize (and normalize) the typed accumulator.
76 abj404_benchmark_state_ref();
77 }
78 }
79
80 if (!function_exists('abj404_benchmark_mark_bootstrap_done')) {
81 /** @return void */
82 function abj404_benchmark_mark_bootstrap_done() {
83 if (!abj404_is_benchmark_request() || !isset($GLOBALS['abj404_benchmark_state'])) {
84 return;
85 }
86 $state = &abj404_benchmark_state_ref();
87 $state['bootstrap_done'] = abj404_now_float();
88 }
89 }
90
91 if (!function_exists('abj404_benchmark_record_db_query')) {
92 /**
93 * @param float $elapsedMs
94 * @return void
95 */
96 function abj404_benchmark_record_db_query($elapsedMs) {
97 if (!abj404_is_benchmark_request() || !isset($GLOBALS['abj404_benchmark_state'])) {
98 return;
99 }
100 $elapsedMs = max(0.0, (float)$elapsedMs);
101 $state = &abj404_benchmark_state_ref();
102 $state['db_query_count']++;
103 $state['db_query_ms'] += $elapsedMs;
104 }
105 }
106
107 if (!function_exists('abj404_benchmark_record_redirect_lookup')) {
108 /**
109 * @param float $elapsedMs
110 * @return void
111 */
112 function abj404_benchmark_record_redirect_lookup($elapsedMs) {
113 if (!abj404_is_benchmark_request() || !isset($GLOBALS['abj404_benchmark_state'])) {
114 return;
115 }
116 $state = &abj404_benchmark_state_ref();
117 $state['redirect_lookup_ms'] += max(0.0, (float)$elapsedMs);
118 }
119 }
120
121 if (!function_exists('abj404_benchmark_emit_headers')) {
122 /** @return void */
123 function abj404_benchmark_emit_headers() {
124 if (!abj404_is_benchmark_request() || headers_sent() || !isset($GLOBALS['abj404_benchmark_state'])) {
125 return;
126 }
127 $state = abj404_benchmark_state_ref();
128 $start = $state['start'];
129 $bootstrapDone = $state['bootstrap_done'];
130 $now = abj404_now_float();
131 $totalMs = ($start > 0.0) ? (($now - $start) * 1000.0) : 0.0;
132 $bootstrapMs = ($start > 0.0 && $bootstrapDone > 0.0) ? (($bootstrapDone - $start) * 1000.0) : 0.0;
133 $dbQueryCount = $state['db_query_count'];
134 $dbQueryMs = $state['db_query_ms'];
135 $redirectLookupMs = $state['redirect_lookup_ms'];
136
137 header(
138 'X-ABJ404-Benchmark: ' .
139 'total_ms=' . round($totalMs, 3) . ';' .
140 'bootstrap_ms=' . round($bootstrapMs, 3) . ';' .
141 'db_query_count=' . $dbQueryCount . ';' .
142 'db_query_ms=' . round($dbQueryMs, 3) . ';' .
143 'redirect_lookup_ms=' . round($redirectLookupMs, 3)
144 );
145 }
146 }
147