@@ -8,28 +8,49 @@ import OpenTelemetryApi
88
99/// Implementation for the Span class that records trace events.
1010public class RecordEventsReadableSpan : ReadableSpan {
11- public var isRecording = true
11+ private let lock : ReadWriteLock = . init( )
12+
13+ fileprivate var internalIsRecording = true
14+ public var isRecording : Bool {
15+ get { lock. withReaderLock { internalIsRecording } }
16+ set {
17+ lock. withWriterLock {
18+ if !internalEnd {
19+ internalIsRecording = newValue
20+ }
21+ }
22+ }
23+ }
1224
13- fileprivate let internalStatusQueue = DispatchQueue ( label: " org.opentelemetry.RecordEventsReadableSpan.internalStatusQueue " , attributes: . concurrent)
14- /// The displayed name of the span.
1525 fileprivate var internalName : String
1626 public var name : String {
17- get {
18- var value = " "
19- internalStatusQueue. sync {
20- value = internalName
27+ get { lock. withReaderLock { internalName } }
28+ set {
29+ lock. withWriterLock {
30+ if !internalEnd {
31+ internalName = newValue
32+ }
2133 }
22- return value
2334 }
35+ }
36+
37+ /// The status of the span.
38+ fileprivate var internalStatus : Status = . unset
39+ public var status : Status {
40+ get { lock. withReaderLock { internalStatus } }
2441 set {
25- internalStatusQueue . sync ( flags : . barrier ) {
42+ lock . withWriterLock {
2643 if !internalEnd {
27- internalName = newValue
44+ internalStatus = newValue
2845 }
2946 }
3047 }
3148 }
3249
50+ /// True if the span is ended.
51+ fileprivate var internalEnd = false
52+ public var hasEnded : Bool { lock. withReaderLock { internalEnd } }
53+
3354 // The config used when constructing this Span.
3455 public private( set) var spanLimits : SpanLimits
3556 /// Contains the identifiers associated with this Span.
@@ -70,44 +91,13 @@ public class RecordEventsReadableSpan: ReadableSpan {
7091 /// Number of events recorded.
7192 public private( set) var totalRecordedEvents = 0
7293
73- /// The status of the span.
74- fileprivate var internalStatus : Status = . unset
75- public var status : Status {
76- get {
77- var value : Status = . unset
78- internalStatusQueue. sync {
79- value = internalStatus
80- }
81- return value
82- }
83- set {
84- internalStatusQueue. sync ( flags: . barrier) {
85- if !internalEnd {
86- internalStatus = newValue
87- }
88- }
89- }
90- }
91-
9294 /// Returns the latency of the Span in seconds. If still active then returns now() - start time.
9395 public var latency : TimeInterval {
9496 return endTime? . timeIntervalSince ( startTime) ?? clock. now. timeIntervalSince ( startTime)
9597 }
9698
9799 /// The end time of the span.
98100 public private( set) var endTime : Date ?
99- /// True if the span is ended.
100- fileprivate var internalEnd = false
101- public var hasEnded : Bool {
102- var value = false
103- internalStatusQueue. sync {
104- value = internalEnd
105- }
106- return value
107- }
108-
109- private let eventsSyncLock = Lock ( )
110- private let attributesSyncLock = Lock ( )
111101
112102 private init ( context: SpanContext ,
113103 name: String ,
@@ -193,43 +183,39 @@ public class RecordEventsReadableSpan: ReadableSpan {
193183 }
194184
195185 public func toSpanData( ) -> SpanData {
196- attributesSyncLock . withLock {
197- return SpanData ( traceId: context. traceId,
198- spanId: context. spanId,
199- traceFlags: context. traceFlags,
200- traceState: context. traceState,
201- parentSpanId: parentContext? . spanId,
202- resource: resource,
203- instrumentationScope: instrumentationScopeInfo,
204- name: name ,
205- kind: kind,
206- startTime: startTime,
207- attributes: attributes. attributes,
208- events: adaptEvents ( ) ,
209- links: adaptLinks ( ) ,
210- status: status ,
211- endTime: endTime ?? clock. now,
212- hasRemoteParent: hasRemoteParent,
213- hasEnded: hasEnded ,
214- totalRecordedEvents: getTotalRecordedEvents ( ) ,
215- totalRecordedLinks: totalRecordedLinks,
216- totalAttributeCount: totalAttributeCount)
186+ lock . withReaderLock {
187+ SpanData ( traceId: context. traceId,
188+ spanId: context. spanId,
189+ traceFlags: context. traceFlags,
190+ traceState: context. traceState,
191+ parentSpanId: parentContext? . spanId,
192+ resource: resource,
193+ instrumentationScope: instrumentationScopeInfo,
194+ name: internalName ,
195+ kind: kind,
196+ startTime: startTime,
197+ attributes: attributes. attributes,
198+ events: lockedAdaptEvents ( ) ,
199+ links: lockedAdaptLinks ( ) ,
200+ status: internalStatus ,
201+ endTime: endTime ?? clock. now,
202+ hasRemoteParent: hasRemoteParent,
203+ hasEnded: internalEnd ,
204+ totalRecordedEvents: totalRecordedEvents ,
205+ totalRecordedLinks: totalRecordedLinks,
206+ totalAttributeCount: totalAttributeCount)
217207 }
218208 }
219209
220- private func adaptEvents( ) -> [ SpanData . Event ] {
221- var sourceEvents = [ SpanData . Event] ( )
222- eventsSyncLock. withLockVoid {
223- sourceEvents = events. array
224- }
210+ private func lockedAdaptEvents( ) -> [ SpanData . Event ] {
225211 var result = [ SpanData . Event] ( )
226- sourceEvents . forEach {
212+ events . array . forEach {
227213 result. append ( SpanData . Event ( name: $0. name, timestamp: $0. timestamp, attributes: $0. attributes) )
228214 }
229215 return result
230216 }
231217
232- private func adaptLinks ( ) -> [ SpanData . Link ] {
218+ private func lockedAdaptLinks ( ) -> [ SpanData . Link ] {
233219 var result = [ SpanData . Link] ( )
234220 let linksRef = links
235221 linksRef. forEach {
@@ -239,8 +225,8 @@ public class RecordEventsReadableSpan: ReadableSpan {
239225 }
240226
241227 public func setAttribute( key: String , value: AttributeValue ? ) {
242- attributesSyncLock . withLockVoid {
243- if !isRecording {
228+ lock . withWriterLock {
229+ if !internalIsRecording {
244230 return
245231 }
246232
@@ -285,8 +271,8 @@ public class RecordEventsReadableSpan: ReadableSpan {
285271 }
286272
287273 private func addEvent( event: SpanData . Event ) {
288- eventsSyncLock . withLockVoid {
289- if !isRecording {
274+ lock . withWriterLock {
275+ if !internalIsRecording {
290276 return
291277 }
292278 events. append ( event)
@@ -299,24 +285,19 @@ public class RecordEventsReadableSpan: ReadableSpan {
299285 }
300286
301287 public func end( time: Date ) {
302- let alreadyEnded = internalStatusQueue . sync ( flags : . barrier ) { ( ) -> Bool in
288+ let alreadyEnded = lock . withWriterLock {
303289 if internalEnd {
304290 return true
305291 }
306292
307293 internalEnd = true
294+ internalIsRecording = false
308295 return false
309296 }
310-
311297 if alreadyEnded {
312298 return
313299 }
314300
315- eventsSyncLock. withLockVoid {
316- attributesSyncLock. withLockVoid {
317- isRecording = false
318- }
319- }
320301 endTime = time
321302 OpenTelemetry . instance. contextProvider. removeContextForSpan ( self )
322303 spanProcessor. onEnd ( span: self )
@@ -327,9 +308,7 @@ public class RecordEventsReadableSpan: ReadableSpan {
327308 }
328309
329310 func getTotalRecordedEvents( ) -> Int {
330- eventsSyncLock. withLock {
331- totalRecordedEvents
332- }
311+ lock. withReaderLock { totalRecordedEvents }
333312 }
334313
335314 /// For testing purposes
0 commit comments