diff --git a/packages/core/ios/Sources/DdTraceImplementation.swift b/packages/core/ios/Sources/DdTraceImplementation.swift index 01762c61f..94d8cf418 100644 --- a/packages/core/ios/Sources/DdTraceImplementation.swift +++ b/packages/core/ios/Sources/DdTraceImplementation.swift @@ -44,14 +44,13 @@ public class DdTraceImplementation: NSObject { public func finishSpan(spanId: NSString, context: NSDictionary, timestampMs: Double, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { objc_sync_enter(self) let optionalSpan = spanDictionary.removeValue(forKey: spanId) - objc_sync_exit(self) - if let span = optionalSpan { set(tags: castAttributesToSwift(context).mergeWithGlobalAttributes(), to: span) let timeIntervalSince1970: TimeInterval = timestampMs / 1_000 span.finish(at: Date(timeIntervalSince1970: timeIntervalSince1970)) } - + objc_sync_exit(self) + resolve(nil) } diff --git a/packages/core/ios/Tests/DdTraceTests.swift b/packages/core/ios/Tests/DdTraceTests.swift index 6c86a6e92..5c7d11585 100644 --- a/packages/core/ios/Tests/DdTraceTests.swift +++ b/packages/core/ios/Tests/DdTraceTests.swift @@ -140,6 +140,10 @@ internal class DdTraceTests: XCTestCase { } func testTracingConcurrently() { + // It is possible and acceptable that a concurrent finishSpan resolve is called on a different thread before we get the lastResolveValue. + // This would override lastResolveValue to be `nil`. To avoid this, we use a different resolve. + func mockFinishResolve(args: Any?) {} + let iterationCount = 30 DispatchQueue.concurrentPerform(iterations: iterationCount) { iteration in tracer.startSpan( @@ -150,7 +154,7 @@ internal class DdTraceTests: XCTestCase { reject: mockReject ) let spanID = lastResolveValue as! NSString - tracer.finishSpan(spanId: spanID, context: testTags, timestampMs: 100, resolve: mockResolve, reject: mockReject) + tracer.finishSpan(spanId: spanID, context: testTags, timestampMs: 100, resolve: mockFinishResolve, reject: mockReject) } XCTAssertEqual(mockNativeTracer.startedSpans.count, iterationCount, "\(mockNativeTracer.startedSpans)")