88use Http \Client \HttpClient ;
99use Psr \Http \Message \RequestInterface ;
1010use Psr \Http \Message \ResponseInterface ;
11+ use Symfony \Component \Stopwatch \Stopwatch ;
12+ use Symfony \Component \Stopwatch \StopwatchEvent ;
1113
1214/**
1315 * The ProfileClient decorates any client that implement both HttpClient and HttpAsyncClient interfaces to gather target
@@ -34,13 +36,19 @@ class ProfileClient implements HttpClient, HttpAsyncClient
3436 */
3537 private $ formatter ;
3638
39+ /**
40+ * @var Stopwatch
41+ */
42+ private $ stopwatch ;
43+
3744 /**
3845 * @param HttpClient|HttpAsyncClient $client The client to profile. Client must implement both HttpClient and
3946 * HttpAsyncClient interfaces.
4047 * @param Collector $collector
4148 * @param Formatter $formatter
49+ * @param Stopwatch $stopwatch
4250 */
43- public function __construct ($ client , Collector $ collector , Formatter $ formatter )
51+ public function __construct ($ client , Collector $ collector , Formatter $ formatter, Stopwatch $ stopwatch )
4452 {
4553 if (!($ client instanceof HttpClient && $ client instanceof HttpAsyncClient)) {
4654 throw new \RuntimeException (sprintf (
@@ -54,6 +62,7 @@ public function __construct($client, Collector $collector, Formatter $formatter)
5462 $ this ->client = $ client ;
5563 $ this ->collector = $ collector ;
5664 $ this ->formatter = $ formatter ;
65+ $ this ->stopwatch = $ stopwatch ;
5766 }
5867
5968 /**
@@ -63,16 +72,20 @@ public function sendAsyncRequest(RequestInterface $request)
6372 {
6473 $ stack = $ this ->collector ->getCurrentStack ();
6574 $ this ->collectRequestInformations ($ request , $ stack );
75+ $ event = $ this ->stopwatch ->start ($ this ->getStopwatchEventName ($ request ));
6676
67- return $ this ->client ->sendAsyncRequest ($ request )->then (function (ResponseInterface $ response ) use ($ stack ) {
68- $ this ->collectResponseInformations ($ response , $ stack );
77+ return $ this ->client ->sendAsyncRequest ($ request )->then (
78+ function (ResponseInterface $ response ) use ($ event , $ stack ) {
79+ $ event ->stop ();
80+ $ this ->collectResponseInformations ($ response , $ event , $ stack );
6981
70- return $ response ;
71- }, function (\Exception $ exception ) use ($ stack ) {
72- $ this ->collectExceptionInformations ($ exception , $ stack );
82+ return $ response ;
83+ }, function (\Exception $ exception ) use ($ event , $ stack ) {
84+ $ this ->collectExceptionInformations ($ exception, $ event , $ stack );
7385
74- throw $ exception ;
75- });
86+ throw $ exception ;
87+ }
88+ );
7689 }
7790
7891 /**
@@ -82,15 +95,18 @@ public function sendRequest(RequestInterface $request)
8295 {
8396 $ stack = $ this ->collector ->getCurrentStack ();
8497 $ this ->collectRequestInformations ($ request , $ stack );
98+ $ event = $ this ->stopwatch ->start ($ this ->getStopwatchEventName ($ request ));
8599
86100 try {
87101 $ response = $ this ->client ->sendRequest ($ request );
102+ $ event ->stop ();
88103
89- $ this ->collectResponseInformations ($ response , $ stack );
104+ $ this ->collectResponseInformations ($ response , $ event , $ stack );
90105
91106 return $ response ;
92107 } catch (\Exception $ e ) {
93- $ this ->collectExceptionInformations ($ e , $ stack );
108+ $ event ->stop ();
109+ $ this ->collectExceptionInformations ($ e , $ event , $ stack );
94110
95111 throw $ e ;
96112 }
@@ -115,32 +131,48 @@ private function collectRequestInformations(RequestInterface $request, Stack $st
115131
116132 /**
117133 * @param ResponseInterface $response
134+ * @param StopwatchEvent $event
118135 * @param Stack|null $stack
119136 */
120- private function collectResponseInformations (ResponseInterface $ response , Stack $ stack = null )
137+ private function collectResponseInformations (ResponseInterface $ response , StopwatchEvent $ event , Stack $ stack = null )
121138 {
122139 if (!$ stack ) {
123140 return ;
124141 }
125142
143+ $ stack ->setDuration ($ event ->getDuration ());
126144 $ stack ->setResponseCode ($ response ->getStatusCode ());
127145 $ stack ->setClientResponse ($ this ->formatter ->formatResponse ($ response ));
128146 }
129147
130148 /**
131- * @param \Exception $exception
132- * @param Stack|null $stack
149+ * @param \Exception $exception
150+ * @param StopwatchEvent $event
151+ * @param Stack|null $stack
133152 */
134- private function collectExceptionInformations (\Exception $ exception , Stack $ stack = null )
153+ private function collectExceptionInformations (\Exception $ exception , StopwatchEvent $ event , Stack $ stack = null )
135154 {
136155 if ($ exception instanceof HttpException) {
137- $ this ->collectResponseInformations ($ exception ->getResponse (), $ stack );
156+ $ this ->collectResponseInformations ($ exception ->getResponse (), $ event , $ stack );
138157 }
139158
140159 if (!$ stack ) {
141160 return ;
142161 }
143162
163+ $ stack ->setDuration ($ event ->getDuration ());
144164 $ stack ->setClientException ($ this ->formatter ->formatException ($ exception ));
145165 }
166+
167+ /**
168+ * Generates the event name.
169+ *
170+ * @param RequestInterface $request
171+ *
172+ * @return string
173+ */
174+ private function getStopwatchEventName (RequestInterface $ request )
175+ {
176+ return sprintf ('%s %s ' , $ request ->getMethod (), $ request ->getUri ()->__toString ());
177+ }
146178}
0 commit comments