Commit 6c74e95d authored by yurys@chromium.org's avatar yurys@chromium.org

Record DevTools metadata events on worker threads when starting recoring tracing based Timeline

This events will be used to figure out if given worker thread is started by the page being profiled and if so we will show messages in the worker on the same Timeline.

BUG=401895

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

git-svn-id: svn://svn.chromium.org/blink/trunk@180072 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent a0a11e8d
......@@ -115,7 +115,7 @@ InspectorTest.didInvokePageFunctionAsync = function(callId, value)
{
var callback = pendingEvalRequests[callId];
if (!callback) {
InspectorTest.addResult("Missing callback for ascyn eval " + callId + ", perhaps callback invoked twice?");
InspectorTest.addResult("Missing callback for async eval " + callId + ", perhaps callback invoked twice?");
return;
}
delete pendingEvalRequests[callId];
......
onmessage = function(event) {
doWork();
setInterval(doWork, 0);
};
var message_id = 0;
function doWork()
{
postMessage("Message #" + message_id++);
}
Tests that worker events are recorded with proper devtools metadata events.
Got DevTools worker metadata event(1): TracingStartedInWorker
Got DevTools worker metadata event(2): TracingStartedInWorker
<html>
<head>
<script src="../../../http/tests/inspector/inspector-test.js"></script>
<script src="../../../http/tests/inspector/timeline-test.js"></script>
<script src="../../tracing-test.js"></script>
<script>
function startWorkerAndRunTest()
{
var worker1 = new Worker("resources/worker.js");
worker1.postMessage("");
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.waitUntilDone();
}
worker1.onmessage = function(event)
{
worker1.onmessage = null;
runTest();
}
}
function startSecondWorker(onActionComplete)
{
var worker2 = new Worker("resources/worker.js");
worker2.postMessage("");
worker2.onmessage = function(event)
{
onActionComplete();
worker2.onmessage = null;
}
}
function test()
{
InspectorTest.invokeWithTracing("startSecondWorker", processTracingEvents);
var workerMetadataEventCount = 0;
function processTracingEvents()
{
InspectorTest.tracingModel.sortedProcesses().forEach(function(process) {
process.sortedThreads().forEach(function(thread) {
thread.events().forEach(processEvent);
});
});
InspectorTest.assertEquals(2, workerMetadataEventCount);
InspectorTest.completeTest();
}
function processEvent(event)
{
if (event.category !== WebInspector.TracingModel.DevToolsMetadataEventCategory || event.name !== WebInspector.TracingModel.DevToolsMetadataEvent.TracingStartedInWorker)
return;
++workerMetadataEventCount;
InspectorTest.assertEquals(InspectorTest.tracingModel.sessionId(), event.args["sessionId"]);
InspectorTest.addResult("Got DevTools worker metadata event(" + workerMetadataEventCount + "): " + event.name);
}
}
</script>
</head>
<body onload="startWorkerAndRunTest()">
<p>
Tests that worker events are recorded with proper devtools metadata events.
</p>
</body>
</html>
......@@ -103,10 +103,14 @@ InspectorController::InspectorController(Page* page, InspectorClient* inspectorC
m_layerTreeAgent = layerTreeAgentPtr.get();
m_agents.append(layerTreeAgentPtr.release());
OwnPtrWillBeRawPtr<InspectorTracingAgent> tracingAgentPtr = InspectorTracingAgent::create(inspectorClient);
OwnPtrWillBeRawPtr<InspectorWorkerAgent> workerAgentPtr = InspectorWorkerAgent::create();
OwnPtrWillBeRawPtr<InspectorTracingAgent> tracingAgentPtr = InspectorTracingAgent::create(inspectorClient, workerAgentPtr.get());
m_tracingAgent = tracingAgentPtr.get();
m_agents.append(tracingAgentPtr.release());
m_agents.append(workerAgentPtr.release());
OwnPtrWillBeRawPtr<InspectorTimelineAgent> timelineAgentPtr(InspectorTimelineAgent::create(m_pageAgent, m_layerTreeAgent,
overlay, InspectorTimelineAgent::PageInspector, inspectorClient));
m_timelineAgent = timelineAgentPtr.get();
......@@ -118,8 +122,6 @@ InspectorController::InspectorController(Page* page, InspectorClient* inspectorC
m_agents.append(PageConsoleAgent::create(injectedScriptManager, m_domAgent, m_timelineAgent, m_tracingAgent));
m_agents.append(InspectorWorkerAgent::create());
ASSERT_ARG(inspectorClient, inspectorClient);
m_injectedScriptManager->injectedScriptHost()->init(m_instrumentingAgents.get(), pageScriptDebugServer);
}
......
......@@ -11,6 +11,7 @@
#include "core/inspector/IdentifiersFactory.h"
#include "core/inspector/InspectorClient.h"
#include "core/inspector/InspectorState.h"
#include "core/inspector/InspectorWorkerAgent.h"
#include "platform/TraceEvent.h"
namespace blink {
......@@ -25,11 +26,12 @@ namespace {
const char devtoolsMetadataEventCategory[] = TRACE_DISABLED_BY_DEFAULT("devtools.timeline");
}
InspectorTracingAgent::InspectorTracingAgent(InspectorClient* client)
InspectorTracingAgent::InspectorTracingAgent(InspectorClient* client, InspectorWorkerAgent* workerAgent)
: InspectorBaseAgent<InspectorTracingAgent>("Tracing")
, m_layerTreeId(0)
, m_client(client)
, m_frontend(0)
, m_workerAgent(workerAgent)
{
}
......@@ -48,7 +50,7 @@ void InspectorTracingAgent::end(ErrorString* errorString)
{
m_state->setBoolean(TracingAgentState::tracingStarted, false);
m_consoleTimelines.clear();
m_frontend->stopped();
notifyTracingStopped();
}
void InspectorTracingAgent::innerStart(const String& categoryFilter, bool fromConsole)
......@@ -72,6 +74,7 @@ void InspectorTracingAgent::emitMetadataEvents()
TRACE_EVENT_INSTANT1(devtoolsMetadataEventCategory, "TracingStartedInPage", "sessionId", sessionId().utf8());
if (m_layerTreeId)
setLayerTreeId(m_layerTreeId);
m_workerAgent->setTracingSessionId(sessionId());
}
void InspectorTracingAgent::setLayerTreeId(int layerTreeId)
......@@ -98,10 +101,16 @@ void InspectorTracingAgent::consoleTimelineEnd(const String& title)
if (!m_consoleTimelines.size()
&& m_state->getBoolean(TracingAgentState::tracingStarted)
&& !m_state->getBoolean(TracingAgentState::tracingStartedFromProtocol))
m_frontend->stopped();
notifyTracingStopped();
m_state->setBoolean(TracingAgentState::tracingStarted, false);
}
void InspectorTracingAgent::notifyTracingStopped()
{
m_frontend->stopped();
m_workerAgent->setTracingSessionId(String());
}
void InspectorTracingAgent::setFrontend(InspectorFrontend* frontend)
{
m_frontend = frontend->tracing();
......
......@@ -15,15 +15,16 @@
namespace blink {
class InspectorClient;
class InspectorWorkerAgent;
class InspectorTracingAgent FINAL
: public InspectorBaseAgent<InspectorTracingAgent>
, public InspectorBackendDispatcher::TracingCommandHandler {
WTF_MAKE_NONCOPYABLE(InspectorTracingAgent);
public:
static PassOwnPtrWillBeRawPtr<InspectorTracingAgent> create(InspectorClient* client)
static PassOwnPtrWillBeRawPtr<InspectorTracingAgent> create(InspectorClient* client, InspectorWorkerAgent* workerAgent)
{
return adoptPtrWillBeNoop(new InspectorTracingAgent(client));
return adoptPtrWillBeNoop(new InspectorTracingAgent(client, workerAgent));
}
// Base agent methods.
......@@ -41,16 +42,18 @@ public:
void setLayerTreeId(int);
private:
explicit InspectorTracingAgent(InspectorClient*);
InspectorTracingAgent(InspectorClient*, InspectorWorkerAgent*);
void emitMetadataEvents();
void innerStart(const String& categoryFilter, bool fromConsole);
String sessionId();
void notifyTracingStopped();
int m_layerTreeId;
InspectorClient* m_client;
Vector<String> m_consoleTimelines;
InspectorFrontend::Tracing* m_frontend;
InspectorWorkerAgent* m_workerAgent;
};
}
......
......@@ -199,6 +199,15 @@ void InspectorWorkerAgent::setAutoconnectToWorkers(ErrorString*, bool value)
m_state->setBoolean(WorkerAgentState::autoconnectToWorkers, value);
}
void InspectorWorkerAgent::setTracingSessionId(const String& sessionId)
{
m_tracingSessionId = sessionId;
if (sessionId.isEmpty())
return;
for (DedicatedWorkers::iterator it = m_dedicatedWorkers.begin(); it != m_dedicatedWorkers.end(); ++it)
it->key->writeTimelineStartedEvent(sessionId);
}
bool InspectorWorkerAgent::shouldPauseDedicatedWorkerOnStart()
{
return m_state->getBoolean(WorkerAgentState::autoconnectToWorkers);
......@@ -209,6 +218,8 @@ void InspectorWorkerAgent::didStartWorkerGlobalScope(WorkerGlobalScopeProxy* wor
m_dedicatedWorkers.set(workerGlobalScopeProxy, url.string());
if (m_inspectorFrontend && m_state->getBoolean(WorkerAgentState::workerInspectionEnabled))
createWorkerFrontendChannel(workerGlobalScopeProxy, url.string());
if (!m_tracingSessionId.isEmpty())
workerGlobalScopeProxy->writeTimelineStartedEvent(m_tracingSessionId);
}
void InspectorWorkerAgent::workerGlobalScopeTerminated(WorkerGlobalScopeProxy* proxy)
......
......@@ -68,6 +68,8 @@ public:
virtual void sendMessageToWorker(ErrorString*, int workerId, const RefPtr<JSONObject>& message) OVERRIDE;
virtual void setAutoconnectToWorkers(ErrorString*, bool value) OVERRIDE;
void setTracingSessionId(const String&);
private:
InspectorWorkerAgent();
void createWorkerFrontendChannelsForExistingWorkers();
......@@ -81,6 +83,7 @@ private:
WorkerChannels m_idToChannel;
typedef HashMap<WorkerGlobalScopeProxy*, String> DedicatedWorkers;
DedicatedWorkers m_dedicatedWorkers;
String m_tracingSessionId;
};
} // namespace blink
......
......@@ -64,6 +64,7 @@ namespace blink {
virtual void connectToInspector(PageInspector*) { }
virtual void disconnectFromInspector() { }
virtual void sendMessageToInspector(const String&) { }
virtual void writeTimelineStartedEvent(const String& sessionId) { }
};
} // namespace blink
......
......@@ -48,6 +48,7 @@
#include "core/workers/WorkerObjectProxy.h"
#include "core/workers/WorkerThreadStartupData.h"
#include "platform/NotImplemented.h"
#include "platform/TraceEvent.h"
#include "platform/heap/Handle.h"
#include "wtf/Functional.h"
#include "wtf/MainThread.h"
......@@ -253,6 +254,22 @@ void WorkerMessagingProxy::sendMessageToInspector(const String& message)
m_workerThread->interruptAndDispatchInspectorCommands();
}
static void dispatchWriteTimelineStartedEvent(ExecutionContext* context, const String& sessionId)
{
TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "TracingStartedInWorker", "sessionId", sessionId.utf8());
}
void WorkerMessagingProxy::writeTimelineStartedEvent(const String& sessionId)
{
if (m_askedToTerminate)
return;
OwnPtr<ExecutionContextTask> task = createCrossThreadTask(dispatchWriteTimelineStartedEvent, String(sessionId));
if (m_workerThread)
m_workerThread->postTask(task.release());
else
m_queuedEarlyTasks.append(task.release());
}
void WorkerMessagingProxy::workerGlobalScopeDestroyed()
{
// This method is always the last to be performed, so the proxy is not needed for communication
......
......@@ -60,6 +60,7 @@ public:
virtual void connectToInspector(WorkerGlobalScopeProxy::PageInspector*) OVERRIDE;
virtual void disconnectFromInspector() OVERRIDE;
virtual void sendMessageToInspector(const String&) OVERRIDE;
virtual void writeTimelineStartedEvent(const String& sessionId) OVERRIDE;
// These methods come from worker context thread via WorkerObjectProxy
// and are called on the worker object thread (e.g. main thread).
......
......@@ -74,6 +74,7 @@ WebInspector.TracingModel.FrameLifecycleEventCategory = "cc,devtools";
WebInspector.TracingModel.DevToolsMetadataEvent = {
TracingStartedInPage: "TracingStartedInPage",
TracingStartedInWorker: "TracingStartedInWorker",
};
WebInspector.TracingModel.prototype = {
......
......@@ -87,6 +87,7 @@ WebInspector.TracingTimelineModel.RecordType = {
CallStack: "CallStack",
SetLayerTreeId: "SetLayerTreeId",
TracingStartedInPage: "TracingStartedInPage",
TracingStartedInWorker: "TracingStartedInWorker",
DecodeImage: "Decode Image",
ResizeImage: "Resize Image",
......
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