@@ -15,7 +15,7 @@ public class Metrics {
1515 let customHeaders : [ String : String ]
1616 let connectionId : UUID
1717
18- private let queue : DispatchQueue
18+ private let lock = NSLock ( )
1919
2020 init ( appName: String ,
2121 metricsInterval: TimeInterval ,
@@ -25,8 +25,7 @@ public class Metrics {
2525 url: URL ,
2626 clientKey: String ,
2727 customHeaders: [ String : String ] = [ : ] ,
28- connectionId: UUID ,
29- queue: DispatchQueue = DispatchQueue ( label: " io.getunleash.metrics " ) ) {
28+ connectionId: UUID ) {
3029 self . appName = appName
3130 self . metricsInterval = metricsInterval
3231 self . clock = clock
@@ -37,68 +36,80 @@ public class Metrics {
3736 self . bucket = Bucket ( clock: clock)
3837 self . customHeaders = customHeaders
3938 self . connectionId = connectionId
40- self . queue = queue
4139 }
4240
4341 func start( ) {
44- if disableMetrics { return }
42+ lock. lock ( )
43+ let isDisabled = self . disableMetrics
44+ lock. unlock ( )
4545
46- queue. sync {
47- self . timer? . cancel ( )
48- self . timer = nil
49- }
46+ if isDisabled { return }
47+
48+ lock. lock ( )
49+ self . timer? . cancel ( )
50+ self . timer = nil
51+ let interval = self . metricsInterval
52+ lock. unlock ( )
5053
5154 let timer = DispatchSource . makeTimerSource ( queue: DispatchQueue . global ( qos: . background) )
52- timer. schedule ( deadline: . now( ) + self . metricsInterval , repeating: self . metricsInterval )
55+ timer. schedule ( deadline: . now( ) + interval , repeating: interval )
5356 timer. setEventHandler { [ weak self] in
5457 guard let self = self else { return }
5558 self . sendMetrics ( )
5659 }
5760 timer. resume ( )
5861
59- queue . sync {
60- self . timer = timer
61- }
62+ lock . lock ( )
63+ self . timer = timer
64+ lock . unlock ( )
6265 }
6366
6467 func stop( ) {
65- queue . sync {
66- self . timer? . cancel ( )
67- self . timer = nil
68- }
68+ lock . lock ( )
69+ self . timer? . cancel ( )
70+ self . timer = nil
71+ lock . unlock ( )
6972 }
7073
7174 func count( name: String , enabled: Bool ) {
72- if disableMetrics { return }
73-
74- queue. sync {
75- var toggle = bucket. toggles [ name] ?? ToggleMetrics ( )
76- if enabled {
77- toggle. yes += 1
78- } else {
79- toggle. no += 1
80- }
81- bucket. toggles [ name] = toggle
75+ lock. lock ( )
76+ let isDisabled = self . disableMetrics
77+ if isDisabled {
78+ lock. unlock ( )
79+ return
8280 }
81+
82+ var toggle = bucket. toggles [ name] ?? ToggleMetrics ( )
83+ if enabled {
84+ toggle. yes += 1
85+ } else {
86+ toggle. no += 1
87+ }
88+ bucket. toggles [ name] = toggle
89+ lock. unlock ( )
8390 }
8491
8592 func countVariant( name: String , variant: String ) {
86- if disableMetrics { return }
87-
88- queue. sync {
89- var toggle = bucket. toggles [ name] ?? ToggleMetrics ( )
90- toggle. variants [ variant, default: 0 ] += 1
91- bucket. toggles [ name] = toggle
93+ lock. lock ( )
94+ let isDisabled = self . disableMetrics
95+ if isDisabled {
96+ lock. unlock ( )
97+ return
9298 }
99+
100+ var toggle = bucket. toggles [ name] ?? ToggleMetrics ( )
101+ toggle. variants [ variant, default: 0 ] += 1
102+ bucket. toggles [ name] = toggle
103+ lock. unlock ( )
93104 }
94105
95106 func sendMetrics( ) {
96- let localBucket : Bucket = queue . sync {
97- bucket. closeBucket ( )
98- let result = bucket
99- bucket = Bucket ( clock: clock )
100- return result
101- }
107+ lock . lock ( )
108+ bucket. closeBucket ( )
109+ let localBucket = bucket
110+ let clockFunction = self . clock
111+ bucket = Bucket ( clock : clockFunction )
112+ lock . unlock ( )
102113
103114 guard !localBucket. isEmpty ( ) else { return }
104115
@@ -122,18 +133,26 @@ public class Metrics {
122133 }
123134
124135 func createRequest( payload: Data ) -> URLRequest {
125- var request = URLRequest ( url: url. appendingPathComponent ( " client/metrics " ) )
136+ lock. lock ( )
137+ let urlValue = self . url
138+ let clientKeyValue = self . clientKey
139+ let appNameValue = self . appName
140+ let connectionIdValue = self . connectionId
141+ let customHeadersValue = self . customHeaders
142+ lock. unlock ( )
143+
144+ var request = URLRequest ( url: urlValue. appendingPathComponent ( " client/metrics " ) )
126145 request. httpMethod = " POST "
127146 request. httpBody = payload
128147 request. addValue ( " application/json " , forHTTPHeaderField: " Accept " )
129148 request. addValue ( " no-cache " , forHTTPHeaderField: " Cache " )
130149 request. addValue ( " application/json " , forHTTPHeaderField: " Content-Type " )
131- request. addValue ( clientKey , forHTTPHeaderField: " Authorization " )
132- request. addValue ( appName , forHTTPHeaderField: " unleash-appname " )
133- request. addValue ( connectionId . uuidString, forHTTPHeaderField: " unleash-connection-id " )
150+ request. addValue ( clientKeyValue , forHTTPHeaderField: " Authorization " )
151+ request. addValue ( appNameValue , forHTTPHeaderField: " unleash-appname " )
152+ request. addValue ( connectionIdValue . uuidString, forHTTPHeaderField: " unleash-connection-id " )
134153 request. setValue ( " unleash-client-swift: \( LibraryInfo . version) " , forHTTPHeaderField: " unleash-sdk " )
135- if !self . customHeaders . isEmpty {
136- for (key, value) in self . customHeaders {
154+ if !customHeadersValue . isEmpty {
155+ for (key, value) in customHeadersValue {
137156 request. setValue ( value, forHTTPHeaderField: key)
138157 }
139158 }
0 commit comments