34
34
* @task apocalypse In Case Of Apocalypse
35
35
* @task validation Validation
36
36
* @task ratelimit Rate Limiting
37
+ * @task phases Startup Phase Timers
37
38
*/
38
39
final class PhabricatorStartup {
39
40
@@ -43,6 +44,7 @@ final class PhabricatorStartup {
43
44
private static $ capturingOutput ;
44
45
private static $ rawInput ;
45
46
private static $ oldMemoryLimit ;
47
+ private static $ phases ;
46
48
47
49
// TODO: For now, disable rate limiting entirely by default. We need to
48
50
// iterate on it a bit for Conduit, some of the specific score levels, and
@@ -89,10 +91,14 @@ public static function getRawInput() {
89
91
90
92
91
93
/**
94
+ * @param float Request start time, from `microtime(true)`.
92
95
* @task hook
93
96
*/
94
- public static function didStartup () {
95
- self ::$ startTime = microtime (true );
97
+ public static function didStartup ($ start_time ) {
98
+ self ::$ startTime = $ start_time ;
99
+
100
+ self ::$ phases = array ();
101
+
96
102
self ::$ accessLog = null ;
97
103
98
104
static $ registered ;
@@ -854,4 +860,58 @@ private static function didRateLimit() {
854
860
exit (1 );
855
861
}
856
862
863
+
864
+ /* -( Startup Timers )----------------------------------------------------- */
865
+
866
+
867
+ /**
868
+ * Record the beginning of a new startup phase.
869
+ *
870
+ * For phases which occur before @{class:PhabricatorStartup} loads, save the
871
+ * time and record it with @{method:recordStartupPhase} after the class is
872
+ * available.
873
+ *
874
+ * @param string Phase name.
875
+ * @task phases
876
+ */
877
+ public static function beginStartupPhase ($ phase ) {
878
+ self ::recordStartupPhase ($ phase , microtime (true ));
879
+ }
880
+
881
+
882
+ /**
883
+ * Record the start time of a previously executed startup phase.
884
+ *
885
+ * For startup phases which occur after @{class:PhabricatorStartup} loads,
886
+ * use @{method:beginStartupPhase} instead. This method can be used to
887
+ * record a time before the class loads, then hand it over once the class
888
+ * becomes available.
889
+ *
890
+ * @param string Phase name.
891
+ * @param float Phase start time, from `microtime(true)`.
892
+ * @task phases
893
+ */
894
+ public static function recordStartupPhase ($ phase , $ time ) {
895
+ self ::$ phases [$ phase ] = $ time ;
896
+ }
897
+
898
+
899
+ /**
900
+ * Get information about startup phase timings.
901
+ *
902
+ * Sometimes, performance problems can occur before we start the profiler.
903
+ * Since the profiler can't examine these phases, it isn't useful in
904
+ * understanding their performance costs.
905
+ *
906
+ * Instead, the startup process marks when it enters various phases using
907
+ * @{method:beginStartupPhase}. A later call to this method can retrieve this
908
+ * information, which can be examined to gain greater insight into where
909
+ * time was spent. The output is still crude, but better than nothing.
910
+ *
911
+ * @task phases
912
+ */
913
+ public static function getPhases () {
914
+ return self ::$ phases ;
915
+ }
916
+
857
917
}
0 commit comments