Commit b9c5a1fe authored by nednguyen@google.com's avatar nednguyen@google.com

Remove StartAsyncDispatchNotifications from inspector_websocket since it's not...

Remove StartAsyncDispatchNotifications from inspector_websocket since it's not needed by tracing backend.

BUG=392044

Review URL: https://codereview.chromium.org/382833004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@282572 0039d316-1c4b-4281-b951-d872f2087c98
parent 7d9081c9
......@@ -5,12 +5,21 @@
import json
import logging
import socket
import threading
import time
from telemetry.core.backends.chrome import websocket
class DispatchNotificationsUntilDoneTimeoutException(Exception):
"""Exception that can be thrown from DispatchNotificationsUntilDone to
indicate timeout exception of the function.
"""
def __init__(self, elapsed_time):
super(DispatchNotificationsUntilDoneTimeoutException, self).__init__()
self.elapsed_time = elapsed_time
class InspectorWebsocket(object):
def __init__(self, notification_handler=None, error_handler=None):
......@@ -18,24 +27,20 @@ class InspectorWebsocket(object):
Args:
notification_handler: A callback for notifications received as a result of
calling DispatchNotifications() or StartAsyncDispatchNotifications().
calling DispatchNotifications() or DispatchNotificationsUntilDone().
Must accept a single JSON object containing the Inspector's
notification. May return True to indicate the stop async dispatching.
notification. May return True to indicate the dispatching is done for
DispatchNotificationsUntilDone.
error_handler: A callback for errors in communicating with the Inspector.
Must accept a single numeric parameter indicated the time elapsed before
the error.
"""
self._socket = None
self._thread = None
self._cur_socket_timeout = 0
self._next_request_id = 0
self._notification_handler = notification_handler
self._error_handler = error_handler
@property
def is_dispatching_async_notifications(self):
return self._thread != None
def Connect(self, url, timeout=10):
assert not self._socket
self._socket = websocket.create_connection(url, timeout=timeout)
......@@ -55,7 +60,6 @@ class InspectorWebsocket(object):
logging.debug('sent [%s]', data)
def SyncRequest(self, req, timeout=10):
assert not self._thread, 'Cannot be used during async dispatching.'
self.SendAndIgnoreResponse(req)
while self._socket:
......@@ -64,28 +68,28 @@ class InspectorWebsocket(object):
return res
def DispatchNotifications(self, timeout=10):
assert not self._thread, 'Cannot be used during async dispatching.'
self._Receive(timeout)
def StartAsyncDispatchNotifications(self):
assert not self._thread, 'Cannot be started twice.'
self._thread = threading.Thread(target=self._AsyncDispatcher)
self._thread.daemon = True
self._thread.start()
def DispatchNotificationsUntilDone(self, timeout):
"""Dispatch notifications until notification_handler return True.
def StopAsyncDispatchNotifications(self):
self._thread.join(timeout=30)
if self._thread.is_alive():
raise RuntimeError('Timed out waiting for async dispatch notifications.')
self._thread = None
Args:
timeout: the total timeout value for dispatching multiple notifications
until done.
"""
def _AsyncDispatcher(self):
if timeout < self._cur_socket_timeout:
self._SetTimeout(timeout)
start_time = time.time()
while self._socket:
try:
if not self._Receive():
if not self._Receive(timeout):
break
except websocket.WebSocketTimeoutException:
pass
elapsed_time = time.time() - start_time
if elapsed_time > timeout:
raise DispatchNotificationsUntilDoneTimeoutException(elapsed_time)
def _SetTimeout(self, timeout):
if self._cur_socket_timeout != timeout:
......
......@@ -28,6 +28,10 @@ class TracingUnsupportedException(Exception):
pass
class TracingTimeoutException(Exception):
pass
class CategoryFilter(object):
def __init__(self, filter_string):
self.excluded = set()
......@@ -110,10 +114,11 @@ class TracingBackend(object):
self._category_filter = None
self._nesting = 0
self._tracing_data = []
self._is_tracing_running = False
@property
def is_tracing_running(self):
return self._inspector_websocket.is_dispatching_async_notifications
return self._is_tracing_running
def StartTracing(self, custom_categories=None, timeout=10):
""" Starts tracing on the first nested call and returns True. Returns False
......@@ -134,12 +139,10 @@ class TracingBackend(object):
if custom_categories:
req['params'] = {'categories': custom_categories}
self._inspector_websocket.SyncRequest(req, timeout)
# Tracing.start will send asynchronous notifications containing trace
# data, until Tracing.end is called.
self._inspector_websocket.StartAsyncDispatchNotifications()
self._is_tracing_running = True
return True
def StopTracing(self):
def StopTracing(self, timeout=30):
""" Stops tracing on the innermost (!) nested call, because we cannot get
results otherwise. Resets _tracing_data on the outermost nested call.
Returns the result of the trace, as TracingTimelineData object.
......@@ -149,7 +152,19 @@ class TracingBackend(object):
if self.is_tracing_running:
req = {'method': 'Tracing.end'}
self._inspector_websocket.SendAndIgnoreResponse(req)
self._inspector_websocket.StopAsyncDispatchNotifications()
# 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._is_tracing_running = False
if self._nesting == 0:
self._category_filter = None
return self._GetTraceResultAndReset()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment