Index: tools/telemetry/telemetry/core/backends/chrome_inspector/tracing_backend.py |
diff --git a/tools/telemetry/telemetry/core/backends/chrome_inspector/tracing_backend.py b/tools/telemetry/telemetry/core/backends/chrome_inspector/tracing_backend.py |
index 0dd0577903bd86f4e968c554b66f4d5934eb42de..6d327938a8282d327375e199e6e22a49235f42db 100644 |
--- a/tools/telemetry/telemetry/core/backends/chrome_inspector/tracing_backend.py |
+++ b/tools/telemetry/telemetry/core/backends/chrome_inspector/tracing_backend.py |
@@ -3,9 +3,12 @@ |
# found in the LICENSE file. |
import logging |
+import socket |
+import time |
from telemetry import decorators |
from telemetry.core.backends.chrome_inspector import inspector_websocket |
+from telemetry.core.backends.chrome_inspector import websocket |
from telemetry.core.platform import tracing_options |
from telemetry.timeline import trace_data as trace_data_module |
@@ -17,14 +20,18 @@ class TracingUnsupportedException(Exception): |
class TracingTimeoutException(Exception): |
pass |
+ |
+class TracingUnrecoverableException(Exception): |
+ pass |
+ |
+ |
class TracingHasNotRunException(Exception): |
pass |
class TracingBackend(object): |
def __init__(self, devtools_port): |
- self._inspector_websocket = inspector_websocket.InspectorWebsocket( |
- self._ErrorHandler) |
+ self._inspector_websocket = inspector_websocket.InspectorWebsocket() |
self._inspector_websocket.RegisterDomain( |
'Tracing', self._NotificationHandler) |
@@ -32,6 +39,7 @@ class TracingBackend(object): |
'ws://127.0.0.1:%i/devtools/browser' % devtools_port) |
self._trace_events = [] |
self._is_tracing_running = False |
+ self._has_received_all_tracing_data = False |
@property |
def is_tracing_running(self): |
@@ -84,23 +92,42 @@ class TracingBackend(object): |
# After Tracing.end, chrome browser will send asynchronous notifications |
# containing trace data. This is until Tracing.tracingComplete is sent, |
# which means there is no trace buffers pending flush. |
- try: |
- self._inspector_websocket.DispatchNotificationsUntilDone(timeout) |
- except \ |
- inspector_websocket.DispatchNotificationsUntilDoneTimeoutException \ |
- as err: |
- raise TracingTimeoutException( |
- 'Trace data was not fully received due to timeout after %s ' |
- 'seconds. If the trace data is big, you may want to increase the ' |
- 'time out amount.' % err.elapsed_time) |
+ self._CollectTracingData(timeout) |
self._is_tracing_running = False |
trace_data_builder.AddEventsTo( |
trace_data_module.CHROME_TRACE_PART, self._trace_events) |
- def _ErrorHandler(self, elapsed): |
- logging.error('Unrecoverable error after %ds reading tracing response.', |
- elapsed) |
- raise |
+ def _CollectTracingData(self, timeout): |
+ """Collects tracing data. Assumes that Tracing.end has already been sent. |
+ |
+ Args: |
+ timeout: The timeout in seconds. |
+ |
+ Raises: |
+ TracingTimeoutException: If more than |timeout| seconds has passed |
+ since the last time any data is received. |
+ TracingUnrecoverableException: If there is a websocket error. |
+ """ |
+ self._has_received_all_tracing_data = False |
+ start_time = time.time() |
+ while True: |
+ try: |
+ self._inspector_websocket.DispatchNotifications(timeout) |
+ start_time = time.time() |
+ except websocket.WebSocketTimeoutException: |
+ pass |
+ except (socket.error, websocket.WebSocketException): |
+ raise TracingUnrecoverableException |
+ |
+ if self._has_received_all_tracing_data: |
+ break |
+ |
+ elapsed_time = time.time() - start_time |
+ if elapsed_time > timeout: |
+ raise TracingTimeoutException( |
+ 'Only received partial trace data due to timeout after %s seconds. ' |
+ 'If the trace data is big, you may want to increase the timeout ' |
+ 'amount.' % elapsed_time) |
def _NotificationHandler(self, res): |
if 'Tracing.dataCollected' == res.get('method'): |
@@ -112,6 +139,7 @@ class TracingBackend(object): |
else: |
logging.warning('Unexpected type in tracing data') |
elif 'Tracing.tracingComplete' == res.get('method'): |
+ self._has_received_all_tracing_data = True |
return True |
def Close(self): |