Skip to content

Commit a015ec6

Browse files
hoxyqfacebook-github-bot
authored andcommitted
Add a mechanism for emitting stashed trace recording (facebook#53078)
Summary: # Changelog: [Internal] When CDP session is created via `HostTarget::connect`, it will ask `HostTargetDelegate` is there is a previously recorded trace that Host wants to display in the Frontend. `TracingAgent` will serialize and send the recording at the initialization time in constructor. Reviewed By: huntie Differential Revision: D79672597
1 parent 646945c commit a015ec6

File tree

6 files changed

+76
-28
lines changed

6 files changed

+76
-28
lines changed

packages/react-native/ReactCommon/jsinspector-modern/HostAgent.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,18 @@ class HostAgent::Impl final {
4141
HostTargetController& targetController,
4242
HostTargetMetadata hostMetadata,
4343
SessionState& sessionState,
44-
VoidExecutor executor)
44+
VoidExecutor executor,
45+
std::optional<tracing::TraceRecordingState> traceRecordingToEmit)
4546
: frontendChannel_(frontendChannel),
4647
targetController_(targetController),
4748
hostMetadata_(std::move(hostMetadata)),
4849
sessionState_(sessionState),
4950
networkIOAgent_(NetworkIOAgent(frontendChannel, std::move(executor))),
50-
tracingAgent_(
51-
TracingAgent(frontendChannel, sessionState, targetController)) {}
51+
tracingAgent_(TracingAgent(
52+
frontendChannel,
53+
sessionState,
54+
targetController,
55+
std::move(traceRecordingToEmit))) {}
5256

5357
~Impl() {
5458
if (isPausedInDebuggerOverlayVisible_) {
@@ -428,7 +432,8 @@ class HostAgent::Impl final {
428432
HostTargetController& targetController,
429433
HostTargetMetadata hostMetadata,
430434
SessionState& sessionState,
431-
VoidExecutor executor) {}
435+
VoidExecutor executor,
436+
std::optional<tracing::TraceRecordingState> traceRecordingToEmit) {}
432437

433438
void handleRequest(const cdp::PreparsedRequest& req) {}
434439
void setCurrentInstanceAgent(std::shared_ptr<InstanceAgent> agent) {}
@@ -441,14 +446,16 @@ HostAgent::HostAgent(
441446
HostTargetController& targetController,
442447
HostTargetMetadata hostMetadata,
443448
SessionState& sessionState,
444-
VoidExecutor executor)
449+
VoidExecutor executor,
450+
std::optional<tracing::TraceRecordingState> traceRecordingToEmit)
445451
: impl_(std::make_unique<Impl>(
446452
*this,
447453
frontendChannel,
448454
targetController,
449455
std::move(hostMetadata),
450456
sessionState,
451-
std::move(executor))) {}
457+
std::move(executor),
458+
std::move(traceRecordingToEmit))) {}
452459

453460
HostAgent::~HostAgent() = default;
454461

packages/react-native/ReactCommon/jsinspector-modern/HostAgent.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,16 @@ class HostAgent final {
3636
* \param hostMetadata Metadata about the host that created this agent.
3737
* \param sessionState The state of the session that created this agent.
3838
* \param executor A void executor to be used by async-aware handlers.
39+
* \param traceRecordingToEmit If set, this is the trace that Host has
40+
* requested to display in the Frontend.
3941
*/
4042
HostAgent(
4143
const FrontendChannel& frontendChannel,
4244
HostTargetController& targetController,
4345
HostTargetMetadata hostMetadata,
4446
SessionState& sessionState,
45-
VoidExecutor executor);
47+
VoidExecutor executor,
48+
std::optional<tracing::TraceRecordingState> traceRecordingToEmit);
4649

4750
HostAgent(const HostAgent&) = delete;
4851
HostAgent(HostAgent&&) = delete;

packages/react-native/ReactCommon/jsinspector-modern/HostTarget.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ class HostTargetSession {
3434
std::unique_ptr<IRemoteConnection> remote,
3535
HostTargetController& targetController,
3636
HostTargetMetadata hostMetadata,
37-
VoidExecutor executor)
37+
VoidExecutor executor,
38+
std::optional<tracing::TraceRecordingState> traceRecordingToEmit)
3839
: remote_(std::make_shared<RAIIRemoteConnection>(std::move(remote))),
3940
frontendChannel_(
4041
[remoteWeak = std::weak_ptr(remote_)](std::string_view message) {
@@ -47,7 +48,8 @@ class HostTargetSession {
4748
targetController,
4849
std::move(hostMetadata),
4950
state_,
50-
std::move(executor)) {}
51+
std::move(executor),
52+
std::move(traceRecordingToEmit)) {}
5153

5254
/**
5355
* Called by CallbackLocalConnection to send a message to this Session's
@@ -206,7 +208,8 @@ std::unique_ptr<ILocalConnection> HostTarget::connect(
206208
std::move(connectionToFrontend),
207209
controller_,
208210
delegate_.getMetadata(),
209-
makeVoidExecutor(executorFromThis()));
211+
makeVoidExecutor(executorFromThis()),
212+
delegate_.unstable_getTraceRecordingThatWillBeEmittedOnInitialization());
210213
session->setCurrentInstance(currentInstance_.get());
211214
sessions_.insert(std::weak_ptr(session));
212215
return std::make_unique<CallbackLocalConnection>(

packages/react-native/ReactCommon/jsinspector-modern/HostTarget.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,19 @@ class HostTargetDelegate : public LoadNetworkResourceDelegate {
146146
throw NotImplementedException(
147147
"LoadNetworkResourceDelegate.loadNetworkResource is not implemented by this host target delegate.");
148148
}
149+
150+
/**
151+
* [Experimental] Will be called at the CDP session initialization to get the
152+
* trace recording that may have been stashed by the Host from the previous
153+
* background session.
154+
*
155+
* \return the trace recording state if there is one that needs to be
156+
* displayed, otherwise std::nullopt.
157+
*/
158+
virtual std::optional<tracing::TraceRecordingState>
159+
unstable_getTraceRecordingThatWillBeEmittedOnInitialization() {
160+
return std::nullopt;
161+
}
149162
};
150163

151164
/**

packages/react-native/ReactCommon/jsinspector-modern/TracingAgent.cpp

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,15 @@ const uint16_t PROFILE_TRACE_EVENT_CHUNK_SIZE = 1;
3838
TracingAgent::TracingAgent(
3939
FrontendChannel frontendChannel,
4040
SessionState& sessionState,
41-
HostTargetController& hostTargetController)
41+
HostTargetController& hostTargetController,
42+
std::optional<tracing::TraceRecordingState> traceRecordingToEmit)
4243
: frontendChannel_(std::move(frontendChannel)),
4344
sessionState_(sessionState),
44-
hostTargetController_(hostTargetController) {}
45+
hostTargetController_(hostTargetController) {
46+
if (traceRecordingToEmit.has_value()) {
47+
emitTraceRecording(std::move(traceRecordingToEmit.value()));
48+
}
49+
}
4550

4651
TracingAgent::~TracingAgent() {
4752
// Agents are owned by the session. If the agent is destroyed, it means that
@@ -86,25 +91,29 @@ bool TracingAgent::handleRequest(const cdp::PreparsedRequest& req) {
8691
// Send response to Tracing.end request.
8792
frontendChannel_(cdp::jsonResult(req.id));
8893

89-
auto dataCollectedCallback = [this](folly::dynamic&& eventsChunk) {
90-
frontendChannel_(cdp::jsonNotification(
91-
"Tracing.dataCollected",
92-
folly::dynamic::object("value", std::move(eventsChunk))));
93-
};
94-
tracing::TraceRecordingStateSerializer::emitAsDataCollectedChunks(
95-
std::move(state),
96-
dataCollectedCallback,
97-
TRACE_EVENT_CHUNK_SIZE,
98-
PROFILE_TRACE_EVENT_CHUNK_SIZE);
99-
100-
frontendChannel_(cdp::jsonNotification(
101-
"Tracing.tracingComplete",
102-
folly::dynamic::object("dataLossOccurred", false)));
103-
94+
emitTraceRecording(std::move(state));
10495
return true;
10596
}
10697

10798
return false;
10899
}
109100

101+
void TracingAgent::emitTraceRecording(
102+
tracing::TraceRecordingState state) const {
103+
auto dataCollectedCallback = [this](folly::dynamic&& eventsChunk) {
104+
frontendChannel_(cdp::jsonNotification(
105+
"Tracing.dataCollected",
106+
folly::dynamic::object("value", std::move(eventsChunk))));
107+
};
108+
tracing::TraceRecordingStateSerializer::emitAsDataCollectedChunks(
109+
std::move(state),
110+
dataCollectedCallback,
111+
TRACE_EVENT_CHUNK_SIZE,
112+
PROFILE_TRACE_EVENT_CHUNK_SIZE);
113+
114+
frontendChannel_(cdp::jsonNotification(
115+
"Tracing.tracingComplete",
116+
folly::dynamic::object("dataLossOccurred", false)));
117+
}
118+
110119
} // namespace facebook::react::jsinspector_modern

packages/react-native/ReactCommon/jsinspector-modern/TracingAgent.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,18 @@ class TracingAgent {
2424
/**
2525
* \param frontendChannel A channel used to send responses to the
2626
* frontend.
27+
* \param sessionState The state of the session that created this agent.
28+
* \param hostTargetController An interface to the HostTarget that this agent
29+
* is attached to. The caller is responsible for ensuring that the
30+
* HostTargetDelegate and underlying HostTarget both outlive the agent.
31+
* \param traceRecordingToEmit If set, this is the trace that Host has
32+
* requested to display in the Frontend.
2733
*/
2834
TracingAgent(
2935
FrontendChannel frontendChannel,
3036
SessionState& sessionState,
31-
HostTargetController& hostTargetController);
37+
HostTargetController& hostTargetController,
38+
std::optional<tracing::TraceRecordingState> traceRecordingToEmit);
3239

3340
~TracingAgent();
3441

@@ -48,6 +55,12 @@ class TracingAgent {
4855
SessionState& sessionState_;
4956

5057
HostTargetController& hostTargetController_;
58+
59+
/**
60+
* Emits the captured Trace Recording state in a series of
61+
* Tracing.dataCollected events, followed by a Tracing.tracingComplete event.
62+
*/
63+
void emitTraceRecording(tracing::TraceRecordingState state) const;
5164
};
5265

5366
} // namespace facebook::react::jsinspector_modern

0 commit comments

Comments
 (0)