PluginProbe
404 Solution / 4.3.0
404 Solution v4.3.0
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 / database / DatabaseStagedFailureClassifier.php

DatabaseStagedFailureClassifier.php in 404 Solution 4.3.0, at includes/database/DatabaseStagedFailureClassifier.php

100 lines 3.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Staged view-build failure policy classifier.
4 *
5 * Converts a stage number and database/PHP error text into the action the
6 * staged-build orchestrator should take.
7 */
8
9 if (!defined('ABSPATH')) {
10 exit;
11 }
12
13 // allow-no-test-found: covered through DatabaseErrorClassifier facade by tests/StageFailurePolicyClassifierTest.php and tests/StagedBuildBufferMissingPreCheckTest.php
14 class ABJ_404_Solution_DatabaseStagedFailureClassifier {
15
16 /** @var ABJ_404_Solution_DatabaseInfrastructureErrorTaxonomy */
17 private $taxonomy;
18
19 /**
20 * @param ABJ_404_Solution_DatabaseInfrastructureErrorTaxonomy $taxonomy
21 */
22 public function __construct(ABJ_404_Solution_DatabaseInfrastructureErrorTaxonomy $taxonomy) {
23 $this->taxonomy = $taxonomy;
24 }
25
26 /**
27 * True when a staged-build query was killed in a way the next tick can
28 * safely resume.
29 *
30 * @param string $errorText
31 * @return bool
32 */
33 public function isResumableStagedKill(string $errorText): bool {
34 if ($errorText === '') {
35 return false;
36 }
37 if ($this->taxonomy->connectivity()->isQueryTimeoutError($errorText)) {
38 return true;
39 }
40 if ($this->taxonomy->connectivity()->isTransientConnectionError($errorText)) {
41 return true;
42 }
43 if ($this->taxonomy->connectivity()->isDeadlockOrLockTimeoutError($errorText)) {
44 return true;
45 }
46 if (stripos($errorText, 'query execution was interrupted') !== false) {
47 return true;
48 }
49 if ($this->taxonomy->connectivity()->isPacketTooLarge($errorText)) {
50 return true;
51 }
52 return false;
53 }
54
55 /**
56 * True when a staged-build failure is a permanent host constraint rather
57 * than a programmer-class SQL error.
58 *
59 * @param string $errorText
60 * @return bool
61 */
62 public function isPermanentHostSideStagedFailure(string $errorText): bool {
63 if ($errorText === '') {
64 return false;
65 }
66 if ($this->isResumableStagedKill($errorText)) {
67 return false;
68 }
69 return ($this->taxonomy->hostState()->isAccessDeniedError($errorText)
70 || $this->taxonomy->hostState()->isReadOnlyError($errorText)
71 || $this->taxonomy->hostState()->isDiskFullError($errorText)
72 || $this->taxonomy->hostState()->isQuotaLimitError($errorText)
73 || $this->taxonomy->hostState()->isOutOfMemoryError($errorText));
74 }
75
76 /**
77 * Classify an error raised by the staged view-build pipeline.
78 *
79 * @param int $stageNumber
80 * @param string $errorText
81 * @return string
82 */
83 public function classifyStageFailure(int $stageNumber, string $errorText): string {
84 if ($errorText === '') {
85 return 'rethrow';
86 }
87 if (stripos($errorText, 'Staged view-build buffer missing') !== false) {
88 return 'resumable';
89 }
90 if ($this->isResumableStagedKill($errorText)) {
91 return 'resumable';
92 }
93 if (!$this->isPermanentHostSideStagedFailure($errorText)) {
94 return 'rethrow';
95 }
96 $policy = ABJ_404_Solution_ViewBuildConfig::stageFailurePolicy($stageNumber);
97 return $policy === 'optional' ? 'skip' : 'halt';
98 }
99 }
100