Skip to content

Commit

Permalink
remove completer
Browse files Browse the repository at this point in the history
  • Loading branch information
denrase committed Sep 3, 2024
1 parent 77e1e11 commit 7246d5e
Show file tree
Hide file tree
Showing 6 changed files with 316 additions and 167 deletions.
2 changes: 1 addition & 1 deletion flutter/example/ios/Runner/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import UIKit
import Flutter
import Sentry

@UIApplicationMain
@main
@objc class AppDelegate: FlutterAppDelegate {
private let _channel = "example.flutter.sentry.io"

Expand Down
175 changes: 162 additions & 13 deletions flutter/lib/src/event_processor/native_app_start_event_processor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,35 +26,31 @@ class NativeAppStartEventProcessor implements EventProcessor {
}
final nativeAppStartIntegration = integrations.first;

if (nativeAppStartIntegration.didAddAppStartMeasurement ||
event is! SentryTransaction ||
options is! SentryFlutterOptions) {
if (event is! SentryTransaction || options is! SentryFlutterOptions) {
return event;
}

AppStartInfo? appStartInfo = nativeAppStartIntegration.appStartInfo;
if (appStartInfo == null) {
return event;
}

AppStartInfo? appStartInfo;
if (!options.autoAppStart) {
final appStartEnd = nativeAppStartIntegration.appStartEnd;
if (appStartEnd != null) {
appStartInfo = await nativeAppStartIntegration.getAppStartInfo();
appStartInfo?.end = appStartEnd;
appStartInfo.end = appStartEnd;
} else {
// If autoAppStart is disabled and appStartEnd is not set, we can't add app starts
return event;
}
} else {
appStartInfo = await nativeAppStartIntegration.getAppStartInfo();
}

final measurement = appStartInfo?.toMeasurement();
final measurement = appStartInfo.toMeasurement();
if (measurement != null) {
event.measurements[measurement.name] = measurement;
nativeAppStartIntegration.didAddAppStartMeasurement = true;
}

if (appStartInfo != null) {
await _attachAppStartSpans(appStartInfo, event.tracer);
}
await _attachAppStartSpans(appStartInfo, event.tracer);

return event;
}
Expand Down Expand Up @@ -158,3 +154,156 @@ class NativeAppStartEventProcessor implements EventProcessor {
return span;
}
}

class NativeAppStartHandler {
final Hub _hub;

NativeAppStartHandler({Hub? hub}) : _hub = hub ?? HubAdapter();

Future<void> call(
AppStartInfo appStartInfo,
SentryFlutterOptions options,
) async {
const screenName = SentryNavigatorObserver.rootScreenName;
final transaction = _hub.startTransaction(
screenName,
SentrySpanOperations.uiLoad,
startTimestamp: appStartInfo.start,
);
final ttidSpan = transaction.startChild(
SentrySpanOperations.uiTimeToInitialDisplay,
description: '$screenName initial display',
startTimestamp: appStartInfo.start,
);
await ttidSpan.finish(endTimestamp: appStartInfo.end);
await transaction.finish(endTimestamp: appStartInfo.end);

if (!options.autoAppStart) {
final appStartEnd = SentryFlutter.appStatEnd;
if (appStartEnd != null) {
appStartInfo.end = appStartEnd;
} else {
// If autoAppStart is disabled and appStartEnd is not set, we can't add app starts
return;
}
}

await attachMeasurements(transaction as SentryTransaction, appStartInfo);
await attachSpans(transaction as SentryTransaction, appStartInfo);
}

Future<void> attachMeasurements(
SentryTransaction transaction, AppStartInfo appStartInfo) async {
final measurement = appStartInfo.toMeasurement();
if (measurement != null) {
transaction.measurements[measurement.name] = measurement;
}
}

Future<void> attachSpans(
SentryTransaction transaction, AppStartInfo appStartInfo) async {
SentryTracer tracer = transaction.tracer;

final transactionTraceId = tracer.context.traceId;
final appStartEnd = appStartInfo.end;
if (appStartEnd == null) {
return;
}

final appStartSpan = await _createAndFinishSpan(
tracer: tracer,
operation: appStartInfo.appStartTypeOperation,
description: appStartInfo.appStartTypeDescription,
parentSpanId: tracer.context.spanId,
traceId: transactionTraceId,
startTimestamp: appStartInfo.start,
endTimestamp: appStartEnd,
);

await _attachNativeSpans(appStartInfo, tracer, appStartSpan);

final pluginRegistrationSpan = await _createAndFinishSpan(
tracer: tracer,
operation: appStartInfo.appStartTypeOperation,
description: appStartInfo.pluginRegistrationDescription,
parentSpanId: appStartSpan.context.spanId,
traceId: transactionTraceId,
startTimestamp: appStartInfo.start,
endTimestamp: appStartInfo.pluginRegistration,
);

final sentrySetupSpan = await _createAndFinishSpan(
tracer: tracer,
operation: appStartInfo.appStartTypeOperation,
description: appStartInfo.sentrySetupDescription,
parentSpanId: appStartSpan.context.spanId,
traceId: transactionTraceId,
startTimestamp: appStartInfo.pluginRegistration,
endTimestamp: appStartInfo.sentrySetupStart,
);

final firstFrameRenderSpan = await _createAndFinishSpan(
tracer: tracer,
operation: appStartInfo.appStartTypeOperation,
description: appStartInfo.firstFrameRenderDescription,
parentSpanId: appStartSpan.context.spanId,
traceId: transactionTraceId,
startTimestamp: appStartInfo.sentrySetupStart,
endTimestamp: appStartEnd,
);

tracer.children.addAll([
appStartSpan,
pluginRegistrationSpan,
sentrySetupSpan,
firstFrameRenderSpan,
]);
}

Future<void> _attachNativeSpans(AppStartInfo appStartInfo,
SentryTracer transaction, SentrySpan parent) async {
await Future.forEach<TimeSpan>(appStartInfo.nativeSpanTimes,
(timeSpan) async {
try {
final span = await _createAndFinishSpan(
tracer: transaction,
operation: appStartInfo.appStartTypeOperation,
description: timeSpan.description,
parentSpanId: parent.context.spanId,
traceId: transaction.context.traceId,
startTimestamp: timeSpan.start,
endTimestamp: timeSpan.end,
);
span.data.putIfAbsent('native', () => true);
transaction.children.add(span);
} catch (e) {
_hub.options.logger(SentryLevel.warning,
'Failed to attach native span to app start transaction: $e');
}
});
}

Future<SentrySpan> _createAndFinishSpan({
required SentryTracer tracer,
required String operation,
required String description,
required SpanId parentSpanId,
required SentryId traceId,
required DateTime startTimestamp,
required DateTime endTimestamp,
}) async {
final span = SentrySpan(
tracer,
SentrySpanContext(
operation: operation,
description: description,
parentSpanId: parentSpanId,
traceId: traceId,
),
_hub,
startTimestamp: startTimestamp,
);
await span.finish(endTimestamp: endTimestamp);
return span;
}
}
Loading

0 comments on commit 7246d5e

Please sign in to comment.