@@ -11,6 +11,7 @@ import kotlinx.coroutines.flow.Flow
11
11
import kotlinx.coroutines.flow.flow
12
12
import kotlinx.coroutines.joinAll
13
13
import kotlinx.coroutines.launch
14
+ import okhttp3.Response
14
15
import kotlin.collections.HashMap
15
16
16
17
const val STORAGE_ADAPTER_KEY = " statsig.cache"
@@ -130,75 +131,82 @@ internal class SpecStore constructor(
130
131
}
131
132
132
133
private suspend fun syncIdListsFromNetwork () {
133
- val response = network.post(
134
- options.api + " /get_id_lists" ,
135
- mapOf (" statsigMetadata" to statsigMetadata),
136
- emptyMap(),
137
- this .options.initTimeoutMs,
138
- ) ? : return
139
- if (! response.isSuccessful) {
140
- return
141
- }
142
- val body = response.body ? : return
143
- val jsonResponse = gson.fromJson<Map <String , IDList >>(body.string()) ? : return
144
- diagnostics.markStart(KeyType .GET_ID_LIST_SOURCES , StepType .PROCESS , additionalMarker = Marker (idListCount = jsonResponse.size))
145
- val tasks = mutableListOf<Job >()
146
-
147
- for ((name, serverList) in jsonResponse) {
148
- var localList = idLists[name]
149
- if (localList == null ) {
150
- localList = IDList (name = name)
151
- idLists[name] = localList
152
- }
153
- if (serverList.url == null || serverList.fileID == null || serverList.creationTime < localList.creationTime) {
154
- continue
134
+ var response: Response ? = null
135
+ try {
136
+ response = network.post(
137
+ options.api + " /get_id_lists" ,
138
+ mapOf (" statsigMetadata" to statsigMetadata),
139
+ emptyMap(),
140
+ this .options.initTimeoutMs,
141
+ ) ? : return
142
+ if (! response.isSuccessful) {
143
+ return
155
144
}
145
+ val body = response.body ? : return
146
+ val jsonResponse = gson.fromJson<Map <String , IDList >>(body.string()) ? : return
147
+ diagnostics.markStart(KeyType .GET_ID_LIST_SOURCES , StepType .PROCESS , additionalMarker = Marker (idListCount = jsonResponse.size))
148
+ val tasks = mutableListOf<Job >()
149
+
150
+ for ((name, serverList) in jsonResponse) {
151
+ var localList = idLists[name]
152
+ if (localList == null ) {
153
+ localList = IDList (name = name)
154
+ idLists[name] = localList
155
+ }
156
+ if (serverList.url == null || serverList.fileID == null || serverList.creationTime < localList.creationTime) {
157
+ continue
158
+ }
159
+
160
+ // check if fileID has changed, and it is indeed a newer file. If so, reset the list
161
+ if (serverList.fileID != localList.fileID && serverList.creationTime >= localList.creationTime) {
162
+ localList = IDList (
163
+ name = name,
164
+ url = serverList.url,
165
+ fileID = serverList.fileID,
166
+ size = 0 ,
167
+ creationTime = serverList.creationTime,
168
+ )
169
+ idLists[name] = localList
170
+ }
171
+ if (serverList.size <= localList.size) {
172
+ continue
173
+ }
156
174
157
- // check if fileID has changed, and it is indeed a newer file. If so, reset the list
158
- if (serverList.fileID != localList.fileID && serverList.creationTime >= localList.creationTime) {
159
- localList = IDList (
160
- name = name,
161
- url = serverList.url,
162
- fileID = serverList.fileID,
163
- size = 0 ,
164
- creationTime = serverList.creationTime,
175
+ tasks.add(
176
+ statsigScope.launch {
177
+ downloadIDList(localList)
178
+ },
165
179
)
166
- idLists[name] = localList
167
- }
168
- if (serverList.size <= localList.size) {
169
- continue
170
180
}
171
181
172
- tasks.add(
173
- statsigScope.launch {
174
- downloadIDList(localList)
175
- },
176
- )
177
- }
178
-
179
- tasks.joinAll()
180
- diagnostics.markEnd(KeyType .GET_ID_LIST_SOURCES , true , StepType .PROCESS )
182
+ tasks.joinAll()
183
+ diagnostics.markEnd(KeyType .GET_ID_LIST_SOURCES , true , StepType .PROCESS )
181
184
182
- // remove deleted id lists
183
- val deletedLists = mutableListOf<String >()
184
- for (name in idLists.keys) {
185
- if (! jsonResponse.containsKey(name)) {
186
- deletedLists.add(name)
185
+ // remove deleted id lists
186
+ val deletedLists = mutableListOf<String >()
187
+ for (name in idLists.keys) {
188
+ if (! jsonResponse.containsKey(name)) {
189
+ deletedLists.add(name)
190
+ }
187
191
}
188
- }
189
- for (name in deletedLists) {
190
- idLists.remove(name)
192
+ for (name in deletedLists) {
193
+ idLists.remove(name)
194
+ }
195
+ } catch (e: Exception ) {
196
+ throw e
197
+ } finally {
198
+ response?.close()
191
199
}
192
200
}
193
201
194
202
private suspend fun downloadIDList (list : IDList ) {
195
203
if (list.url == null ) {
196
204
return
197
205
}
198
-
206
+ var response : Response ? = null
199
207
try {
200
208
diagnostics.markStart(KeyType .GET_ID_LIST , StepType .NETWORK_REQUEST , additionalMarker = Marker (url = list.url))
201
- val response = network.getExternal(list.url, mapOf (" Range" to " bytes=${list.size} -" ))
209
+ response = network.getExternal(list.url, mapOf (" Range" to " bytes=${list.size} -" ))
202
210
diagnostics.markEnd(KeyType .GET_ID_LIST , response?.isSuccessful == = true , StepType .NETWORK_REQUEST , additionalMarker = Marker (url = list.url, statusCode = response?.code, sdkRegion = response?.headers?.get(" x-statsig-region" )))
203
211
204
212
if (response?.isSuccessful != = true ) {
@@ -234,6 +242,8 @@ internal class SpecStore constructor(
234
242
errorBoundary.logException(" downloadIDList" , e)
235
243
println (" [Statsig]: An exception was caught: $e " )
236
244
diagnostics.markEnd(KeyType .GET_ID_LIST , false , StepType .NETWORK_REQUEST , additionalMarker = Marker (url = list.url))
245
+ } finally {
246
+ response?.close()
237
247
}
238
248
}
239
249
@@ -424,16 +434,19 @@ internal class SpecStore constructor(
424
434
}
425
435
426
436
suspend fun downloadConfigSpecs (): APIDownloadedConfigs ? {
437
+ var response: Response ? = null
427
438
try {
428
- val specs = this .network.downloadConfigSpecs(this .lastUpdateTime, this .options.initTimeoutMs) ? : return null
429
- val configs = gson.fromJson(specs .body?.charStream(), APIDownloadedConfigs ::class .java)
439
+ response = this .network.downloadConfigSpecs(this .lastUpdateTime, this .options.initTimeoutMs) ? : return null
440
+ val configs = gson.fromJson(response .body?.charStream(), APIDownloadedConfigs ::class .java)
430
441
if (configs.hasUpdates) {
431
442
this .lastUpdateTime = configs.time
432
443
}
433
444
return configs
434
445
} catch (e: Exception ) {
435
446
errorBoundary.logException(" downloadConfigSpecs" , e)
436
447
println (" [Statsig]: An exception was caught: $e " )
448
+ } finally {
449
+ response?.close()
437
450
}
438
451
return null
439
452
}
0 commit comments