Skip to content

Commit dfde71c

Browse files
authored
Fix: Thread running at User-initiated quality-of-service for Session replay (#4439)
AVFoundation video maker runs on a lower QoS than user-initiated processes, and the thread sanitizer complains about waiting for it on a higher-level thread. We are changing the QoS of our call to create video.
1 parent f31b069 commit dfde71c

File tree

3 files changed

+14
-4
lines changed

3 files changed

+14
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ via the option `swizzleClassNameExclude`.
1919
- Finish TTID correctly when viewWillAppear is skipped (#4417)
2020
- Swizzling RootUIViewController if ignored by `swizzleClassNameExclude` (#4407)
2121
- Data race in SentrySwizzleInfo.originalCalled (#4434)
22+
- Thread running at user-initiated quality-of-service for session replay (#4439)
2223

2324

2425
### Improvements

Sources/Sentry/SentrySessionReplayIntegration.m

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,12 @@ - (void)startWithOptions:(SentryReplayOptions *)replayOptions
281281
= (NSInteger)(shouldReplayFullSession ? replayOptions.sessionSegmentDuration + 1
282282
: replayOptions.errorReplayDuration + 1);
283283

284+
dispatch_queue_attr_t attributes = dispatch_queue_attr_make_with_qos_class(
285+
DISPATCH_QUEUE_SERIAL, DISPATCH_QUEUE_PRIORITY_LOW, 0);
286+
SentryDispatchQueueWrapper *dispatchQueue =
287+
[[SentryDispatchQueueWrapper alloc] initWithName:"io.sentry.session-replay"
288+
attributes:attributes];
289+
284290
self.sessionReplay = [[SentrySessionReplay alloc]
285291
initWithReplayOptions:replayOptions
286292
replayFolderPath:docs
@@ -290,7 +296,7 @@ - (void)startWithOptions:(SentryReplayOptions *)replayOptions
290296
touchTracker:_touchTracker
291297
dateProvider:SentryDependencyContainer.sharedInstance.dateProvider
292298
delegate:self
293-
dispatchQueue:[[SentryDispatchQueueWrapper alloc] init]
299+
dispatchQueue:dispatchQueue
294300
displayLinkWrapper:[[SentryDisplayLinkWrapper alloc] init]];
295301

296302
[self.sessionReplay

Tests/SentryTests/Integrations/SessionReplay/SentrySessionReplayTests.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ class SentrySessionReplayTests: XCTestCase {
1717
private class TestReplayMaker: NSObject, SentryReplayVideoMaker {
1818
var screens = [String]()
1919

20+
var createVideoCallBack: ((SentryVideoInfo) -> Void)?
21+
2022
struct CreateVideoCall {
2123
var beginning: Date
2224
var end: Date
@@ -30,6 +32,7 @@ class SentrySessionReplayTests: XCTestCase {
3032
try? "Video Data".write(to: outputFileURL, atomically: true, encoding: .utf8)
3133
let videoInfo = SentryVideoInfo(path: outputFileURL, height: 1_024, width: 480, duration: end.timeIntervalSince(beginning), frameCount: 5, frameRate: 1, start: beginning, end: end, fileSize: 10, screens: screens)
3234

35+
createVideoCallBack?(videoInfo)
3336
return [videoInfo]
3437
}
3538

@@ -63,7 +66,7 @@ class SentrySessionReplayTests: XCTestCase {
6366
var lastReplayId: SentryId?
6467
var currentScreen: String?
6568

66-
func getSut(options: SentryReplayOptions = .init(sessionSampleRate: 0, onErrorSampleRate: 0) ) -> SentrySessionReplay {
69+
func getSut(options: SentryReplayOptions = .init(sessionSampleRate: 0, onErrorSampleRate: 0), dispatchQueue: SentryDispatchQueueWrapper = TestSentryDispatchQueueWrapper() ) -> SentrySessionReplay {
6770
return SentrySessionReplay(replayOptions: options,
6871
replayFolderPath: cacheFolder,
6972
screenshotProvider: screenshotProvider,
@@ -72,7 +75,7 @@ class SentrySessionReplayTests: XCTestCase {
7275
touchTracker: SentryTouchTracker(dateProvider: dateProvider, scale: 0),
7376
dateProvider: dateProvider,
7477
delegate: self,
75-
dispatchQueue: TestSentryDispatchQueueWrapper(),
78+
dispatchQueue: dispatchQueue,
7679
displayLinkWrapper: displayLink)
7780
}
7881

@@ -147,7 +150,7 @@ class SentrySessionReplayTests: XCTestCase {
147150
XCTAssertNotNil(fixture.lastReplayRecording)
148151
assertFullSession(sut, expected: true)
149152
}
150-
153+
151154
func testReplayScreenNames() throws {
152155
let fixture = Fixture()
153156
let sut = fixture.getSut(options: SentryReplayOptions(sessionSampleRate: 1, onErrorSampleRate: 1))

0 commit comments

Comments
 (0)