getsentry/sentry-cocoa

Create the profiling envelope item on a background thread

philipphofmann opened this issue · 1 comments

Description

Currently, the tracer creates the profile envelope item, which calls slicing the profiling data on the calling thread of SentryTracer.finishInternal here

- (void)captureTransactionWithProfile:(SentryTransaction *)transaction
startTimestamp:(NSDate *)startTimestamp
{
SentryEnvelopeItem *profileEnvelopeItem =
[SentryProfiler createProfilingEnvelopeItemForTransaction:transaction
startTimestamp:startTimestamp];
if (!profileEnvelopeItem) {
[_hub captureTransaction:transaction withScope:_hub.scope];
return;
}
SENTRY_LOG_DEBUG(@"Capturing transaction id %@ with profiling data attached for tracer id %@.",
transaction.eventId.sentryIdString, self.internalID.sentryIdString);
[_hub captureTransaction:transaction
withScope:_hub.scope
additionalEnvelopeItems:@[ profileEnvelopeItem ]];
}

When the profile lasts for a few seconds, this could noticeably block the main thread. With #3826 the captureTransaction in the hub already happens on a background thread. Moving createProfilingEnvelopeItemForTransaction to a background thread is a bit trickier, because if the tracer gets deallocated in the meantime, it might remove the profiling payload in dealloc:

- (void)dealloc
{
#if SENTRY_TARGET_PROFILING_SUPPORTED
if (self.isProfiling) {
sentry_discardProfilerForTracer(self.internalID);
}
#endif // SENTRY_TARGET_PROFILING_SUPPORTED
}

While we can somehow fix this problem with the current solution, continuous profiling (#3555) will change our current approach, and the solution could get outdated. @armcknight, does it make sense to consider this point while moving towards continuous profiling (#3555)?

It does make sense to consider for the new implementation, definitely. For legacy profiling, I think it should be fine to move things to a bg thread once we have the transaction created by the tracer. There may be a few accesses of the tracer via the transaction from profiler code, but those could be replaced with parameters in the profiling methods/functions that are called so the values can be captured before offloading to the bg thread, risking deallocation.