@@ -71,7 +71,8 @@ public class Telemetry: Subscriber {
71
71
72
72
internal var session : any HTTPSession
73
73
internal var host : String = HTTPClient . getDefaultAPIHost ( )
74
- var sampleRate : Double = 1.0 // inital sample rate should be 1.0, will be downsampled on start
74
+ @Atomic internal var sampleRate : Double = 1.0 // inital sample rate should be 1.0, will be downsampled on start
75
+ internal var sampleRateTest : Atomic < Double > { _sampleRate }
75
76
private var flushTimer : Int = 30
76
77
internal var maxQueueSize : Int = 20
77
78
var errorLogSizeMax : Int = 4000
@@ -85,29 +86,28 @@ public class Telemetry: Subscriber {
85
86
86
87
internal var queue = [ RemoteMetric] ( )
87
88
private var queueBytes = 0
88
- private var queueSizeExceeded = false
89
- private var seenErrors = [ String: Int] ( )
90
- internal var started = false
91
- private var rateLimitEndTime : TimeInterval = 0
92
- internal var flushFirstError = true
89
+ @Atomic internal var started = false
90
+ @Atomic private var rateLimitEndTime : TimeInterval = 0
91
+ @Atomic internal var flushFirstError = true
92
+ internal var flushFirstErrorTest : Atomic < Bool > { _flushFirstError }
93
93
private var telemetryQueue = DispatchQueue ( label: " telemetryQueue " )
94
94
private var updateQueue = DispatchQueue ( label: " updateQueue " )
95
95
private var telemetryTimer : QueueTimer ?
96
96
97
97
/// Starts the Telemetry send loop. Requires both `enable` to be set and a configuration to be retrieved from Segment.
98
98
func start( ) {
99
99
guard enable, !started, sampleRate > 0.0 && sampleRate <= 1.0 else { return }
100
- started = true
100
+ _started . set ( true )
101
101
102
102
// Queue contents were sampled at the default 100%
103
103
// the values on flush will be adjusted in the send function
104
104
if Double . random ( in: 0 ... 1 ) > sampleRate {
105
105
resetQueue ( )
106
106
}
107
107
108
- self . telemetryTimer = QueueTimer ( interval: . seconds( self . flushTimer) , queue: . main ) { [ weak self] in
108
+ self . telemetryTimer = QueueTimer ( interval: . seconds( self . flushTimer) , queue: updateQueue ) { [ weak self] in
109
109
if ( !( self ? . enable ?? false ) ) {
110
- self ? . started = false
110
+ self ? . _started . set ( false )
111
111
self ? . telemetryTimer? . suspend ( )
112
112
}
113
113
self ? . flush ( )
@@ -118,17 +118,16 @@ public class Telemetry: Subscriber {
118
118
func reset( ) {
119
119
telemetryTimer? . suspend ( )
120
120
resetQueue ( )
121
- seenErrors. removeAll ( )
122
- started = false
123
- rateLimitEndTime = 0
121
+ _started. set ( false )
122
+ _rateLimitEndTime. set ( 0 )
124
123
}
125
124
126
125
/// Increments a metric with the provided tags.
127
126
/// - Parameters:
128
127
/// - metric: The metric name.
129
128
/// - buildTags: A closure to build the tags dictionary.
130
129
func increment( metric: String , buildTags: ( inout [ String : String ] ) -> Void ) {
131
- guard enable, sampleRate > 0.0 && sampleRate <= 1.0 , metric. hasPrefix ( Telemetry . METRICS_BASE_TAG) , queueHasSpace ( ) else { return }
130
+ guard enable, sampleRate > 0.0 && sampleRate <= 1.0 , metric. hasPrefix ( Telemetry . METRICS_BASE_TAG) else { return }
132
131
if Double . random ( in: 0 ... 1 ) > sampleRate { return }
133
132
134
133
var tags = [ String: String] ( )
@@ -144,7 +143,7 @@ public class Telemetry: Subscriber {
144
143
/// - log: The log data.
145
144
/// - buildTags: A closure to build the tags dictionary.
146
145
func error( metric: String , log: String , buildTags: ( inout [ String : String ] ) -> Void ) {
147
- guard enable, sampleRate > 0.0 && sampleRate <= 1.0 , metric. hasPrefix ( Telemetry . METRICS_BASE_TAG) , queueHasSpace ( ) else { return }
146
+ guard enable, sampleRate > 0.0 && sampleRate <= 1.0 , metric. hasPrefix ( Telemetry . METRICS_BASE_TAG) else { return }
148
147
if Double . random ( in: 0 ... 1 ) > sampleRate { return }
149
148
150
149
var tags = [ String: String] ( )
@@ -164,7 +163,7 @@ public class Telemetry: Subscriber {
164
163
addRemoteMetric ( metric: metric, tags: filteredTags, log: logData)
165
164
166
165
if ( flushFirstError) {
167
- flushFirstError = false
166
+ _flushFirstError . set ( false )
168
167
flush ( )
169
168
}
170
169
}
@@ -178,14 +177,14 @@ public class Telemetry: Subscriber {
178
177
if rateLimitEndTime > Date ( ) . timeIntervalSince1970 {
179
178
return
180
179
}
181
- rateLimitEndTime = 0
180
+ _rateLimitEndTime . set ( 0 )
182
181
183
182
do {
184
183
try send ( )
185
184
queueBytes = 0
186
185
} catch {
187
186
errorHandler ? ( error)
188
- sampleRate = 0.0
187
+ _sampleRate . set ( 0.0 )
189
188
}
190
189
}
191
190
}
@@ -200,7 +199,6 @@ public class Telemetry: Subscriber {
200
199
sendQueue. append ( metric)
201
200
}
202
201
queueBytes = 0
203
- queueSizeExceeded = false
204
202
205
203
let payload = try JSONEncoder ( ) . encode ( [ " series " : sendQueue] )
206
204
var request = upload ( apiHost: host)
@@ -214,7 +212,7 @@ public class Telemetry: Subscriber {
214
212
215
213
if let httpResponse = response as? HTTPURLResponse , httpResponse. statusCode == 429 {
216
214
if let retryAfter = httpResponse. allHeaderFields [ " Retry-After " ] as? String , let retryAfterSeconds = TimeInterval ( retryAfter) {
217
- self . rateLimitEndTime = retryAfterSeconds + Date( ) . timeIntervalSince1970
215
+ self . _rateLimitEndTime . set ( retryAfterSeconds + Date( ) . timeIntervalSince1970)
218
216
}
219
217
}
220
218
}
@@ -255,6 +253,8 @@ public class Telemetry: Subscriber {
255
253
return
256
254
}
257
255
256
+ guard queue. count < maxQueueSize else { return }
257
+
258
258
let newMetric = RemoteMetric (
259
259
type: METRIC_TYPE,
260
260
metric: metric,
@@ -266,8 +266,6 @@ public class Telemetry: Subscriber {
266
266
if queueBytes + newMetricSize <= maxQueueBytes {
267
267
queue. append ( newMetric)
268
268
queueBytes += newMetricSize
269
- } else {
270
- queueSizeExceeded = true
271
269
}
272
270
}
273
271
}
@@ -284,7 +282,7 @@ public class Telemetry: Subscriber {
284
282
285
283
private func systemUpdate( system: System ) {
286
284
if let settings = system. settings, let sampleRate = settings. metrics ? [ " sampleRate " ] ? . doubleValue {
287
- self . sampleRate = sampleRate
285
+ self . _sampleRate . set ( sampleRate)
288
286
start ( )
289
287
}
290
288
}
@@ -297,19 +295,10 @@ public class Telemetry: Subscriber {
297
295
return request
298
296
}
299
297
300
- private func queueHasSpace( ) -> Bool {
301
- var under = false
302
- telemetryQueue. sync {
303
- under = queue. count < maxQueueSize
304
- }
305
- return under
306
- }
307
-
308
298
private func resetQueue( ) {
309
299
telemetryQueue. sync {
310
300
queue. removeAll ( )
311
301
queueBytes = 0
312
- queueSizeExceeded = false
313
302
}
314
303
}
315
304
}
0 commit comments