Skip to content

Commit

Permalink
Merge branch 'main' into feat/improve-frame-tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
buenaflor authored Nov 1, 2024
2 parents 63da945 + 7c7c64f commit 3b64c28
Show file tree
Hide file tree
Showing 16 changed files with 289 additions and 137 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/testflight.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v4
- uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 # [email protected]
- run: xcodes select 15.0.1
- uses: ruby/setup-ruby@f26937343756480a8cb3ae1f623b9c8d89ed6984 # pin@v1.196.0
- uses: ruby/setup-ruby@7bae1d00b5db9166f4f0fc47985a3a5702cb58f0 # pin@v1.197.0
with:
ruby-version: '2.7.5'
bundler-cache: true
Expand Down
26 changes: 24 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Unreleased

## Features
### Features

- Improve frame tracking accuracy ([#2372](https://github.com/getsentry/sentry-dart/pull/2372))
- Introduces our custom `WidgetsBinding` that tracks a frame starting from `handleBeginFrame` and ending in `handleDrawFrame`, this is approximately the [buildDuration](https://api.flutter.dev/flutter/dart-ui/FrameTiming/buildDuration.html) time
Expand All @@ -18,11 +18,33 @@
}
```
- ⚠️ Frame tracking will be disabled if a different binding is used
- Add screenshot to `SentryFeedbackWidget` ([#2369](https://github.com/getsentry/sentry-dart/pull/2369))
- Use `SentryFlutter.captureScreenshot` to create a screenshot attachment
- Call `SentryFeedbackWidget` with this attachment to add it to the user feedback

```dart
final id = await Sentry.captureMessage('UserFeedback');
final screenshot = await SentryFlutter.captureScreenshot();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SentryFeedbackWidget(
associatedEventId: id,
screenshot: screenshot,
),
fullscreenDialog: true,
),
);
```

### Enhancements

- Cache parsed DSN ([#2365](https://github.com/getsentry/sentry-dart/pull/2365))

- Handle backpressure earlier in pipeline ([#2371](https://github.com/getsentry/sentry-dart/pull/2371))
- Drops max un-awaited parallel tasks earlier, so event processors & callbacks are not executed for them.
- Change by setting `SentryOptions.maxQueueSize`. Default is 30.

## 8.10.0-beta.2

### Fixes
Expand Down
69 changes: 49 additions & 20 deletions dart/lib/src/sentry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import 'sentry_options.dart';
import 'sentry_user_feedback.dart';
import 'tracing.dart';
import 'sentry_attachment/sentry_attachment.dart';
import 'transport/data_category.dart';
import 'transport/task_queue.dart';

/// Configuration options callback
typedef OptionsConfiguration = FutureOr<void> Function(SentryOptions);
Expand All @@ -34,6 +36,7 @@ typedef AppRunner = FutureOr<void> Function();
/// Sentry SDK main entry point
class Sentry {
static Hub _hub = NoOpHub();
static TaskQueue<SentryId> _taskQueue = NoOpTaskQueue();

Sentry._();

Expand All @@ -56,6 +59,11 @@ class Sentry {
if (config is Future) {
await config;
}
_taskQueue = DefaultTaskQueue<SentryId>(
sentryOptions.maxQueueSize,
sentryOptions.logger,
sentryOptions.recorder,
);
} catch (exception, stackTrace) {
sentryOptions.logger(
SentryLevel.error,
Expand Down Expand Up @@ -181,12 +189,17 @@ class Sentry {
Hint? hint,
ScopeCallback? withScope,
}) =>
_hub.captureEvent(
event,
stackTrace: stackTrace,
hint: hint,
withScope: withScope,
);
_taskQueue.enqueue(
() => _hub.captureEvent(
event,
stackTrace: stackTrace,
hint: hint,
withScope: withScope,
),
SentryId.empty(),
event.type != null
? DataCategory.fromItemType(event.type!)
: DataCategory.unknown);

/// Reports the [throwable] and optionally its [stackTrace] to Sentry.io.
static Future<SentryId> captureException(
Expand All @@ -195,11 +208,15 @@ class Sentry {
Hint? hint,
ScopeCallback? withScope,
}) =>
_hub.captureException(
throwable,
stackTrace: stackTrace,
hint: hint,
withScope: withScope,
_taskQueue.enqueue(
() => _hub.captureException(
throwable,
stackTrace: stackTrace,
hint: hint,
withScope: withScope,
),
SentryId.empty(),
DataCategory.error,
);

/// Reports a [message] to Sentry.io.
Expand All @@ -211,13 +228,17 @@ class Sentry {
Hint? hint,
ScopeCallback? withScope,
}) =>
_hub.captureMessage(
message,
level: level,
template: template,
params: params,
hint: hint,
withScope: withScope,
_taskQueue.enqueue(
() => _hub.captureMessage(
message,
level: level,
template: template,
params: params,
hint: hint,
withScope: withScope,
),
SentryId.empty(),
DataCategory.unknown,
);

/// Reports a [userFeedback] to Sentry.io.
Expand All @@ -236,7 +257,15 @@ class Sentry {
Hint? hint,
ScopeCallback? withScope,
}) =>
_hub.captureFeedback(feedback, hint: hint, withScope: withScope);
_taskQueue.enqueue(
() => _hub.captureFeedback(
feedback,
hint: hint,
withScope: withScope,
),
SentryId.empty(),
DataCategory.unknown,
);

/// Close the client SDK
static Future<void> close() async {
Expand All @@ -251,7 +280,7 @@ class Sentry {
/// Last event id recorded by the current Hub
static SentryId get lastEventId => _hub.lastEventId;

/// Adds a breacrumb to the current Scope
/// Adds a breadcrumb to the current Scope
static Future<void> addBreadcrumb(Breadcrumb crumb, {Hint? hint}) =>
_hub.addBreadcrumb(crumb, hint: hint);

Expand Down
10 changes: 1 addition & 9 deletions dart/lib/src/sentry_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import 'transport/http_transport.dart';
import 'transport/noop_transport.dart';
import 'transport/rate_limiter.dart';
import 'transport/spotlight_http_transport.dart';
import 'transport/task_queue.dart';
import 'utils/isolate_utils.dart';
import 'utils/regex_utils.dart';
import 'utils/stacktrace_utils.dart';
Expand All @@ -39,10 +38,6 @@ const _defaultIpAddress = '{{auto}}';
/// Logs crash reports and events to the Sentry.io service.
class SentryClient {
final SentryOptions _options;
late final _taskQueue = TaskQueue<SentryId?>(
_options.maxQueueSize,
_options.logger,
);

final Random? _random;

Expand Down Expand Up @@ -630,9 +625,6 @@ class SentryClient {
Future<SentryId?> _attachClientReportsAndSend(SentryEnvelope envelope) {
final clientReport = _options.recorder.flush();
envelope.addClientReport(clientReport);
return _taskQueue.enqueue(
() => _options.transport.send(envelope),
SentryId.empty(),
);
return _options.transport.send(envelope);
}
}
42 changes: 37 additions & 5 deletions dart/lib/src/transport/task_queue.dart
Original file line number Diff line number Diff line change
@@ -1,21 +1,41 @@
import 'dart:async';

import 'package:meta/meta.dart';

import '../../sentry.dart';
import '../client_reports/client_report_recorder.dart';
import '../client_reports/discard_reason.dart';
import 'data_category.dart';

typedef Task<T> = Future<T> Function();

class TaskQueue<T> {
TaskQueue(this._maxQueueSize, this._logger);
@internal
abstract class TaskQueue<T> {
Future<T> enqueue(Task<T> task, T fallbackResult, DataCategory category);
}

@internal
class DefaultTaskQueue<T> implements TaskQueue<T> {
DefaultTaskQueue(this._maxQueueSize, this._logger, this._recorder);

final int _maxQueueSize;
final SentryLogger _logger;
final ClientReportRecorder _recorder;

int _queueCount = 0;

Future<T> enqueue(Task<T> task, T fallbackResult) async {
@override
Future<T> enqueue(
Task<T> task,
T fallbackResult,
DataCategory category,
) async {
if (_queueCount >= _maxQueueSize) {
_logger(SentryLevel.warning,
'Task dropped due to backpressure. Avoid capturing in a tight loop.');
_recorder.recordLostEvent(DiscardReason.queueOverflow, category);
_logger(
SentryLevel.warning,
'Task dropped due to reaching max ($_maxQueueSize} parallel tasks.).',
);
return fallbackResult;
} else {
_queueCount++;
Expand All @@ -27,3 +47,15 @@ class TaskQueue<T> {
}
}
}

@internal
class NoOpTaskQueue<T> implements TaskQueue<T> {
@override
Future<T> enqueue(
Task<T> task,
T fallbackResult,
DataCategory category,
) {
return task();
}
}
Loading

0 comments on commit 3b64c28

Please sign in to comment.