5
5
import json
6
6
import re
7
7
from datetime import datetime
8
- from typing import Any
8
+ from importlib .metadata import version
9
+ from typing import Any , Final
9
10
10
11
from explainaboard import get_processor
11
12
from explainaboard .loaders .file_loader import FileLoaderReturn
26
27
27
28
class SystemModel (System ):
28
29
29
- _SYSTEM_OUTPUT_CONST = "__SYSOUT__"
30
+ _SYSTEM_OUTPUT_CONST : Final = "__SYSOUT__"
31
+ _CURRENT_SDK_VERSION : Final = version ("explainaboard" )
30
32
"""Same as System but implements several helper functions that retrieves
31
33
additional information and persists data to the DB.
32
34
"""
@@ -150,12 +152,17 @@ def save_system_output(
150
152
)
151
153
152
154
def update_overall_statistics (
153
- self , session : ClientSession | None = None , force_update = False
155
+ self , session : ClientSession , force_update = False
154
156
) -> None :
155
- """regenerates overall statistics and updates cache"""
157
+ """If the analysis is outdated or if `force_update`, the analysis is
158
+ regenerated and the cache is updated."""
156
159
properties = self ._get_private_properties (session = session )
157
160
if not force_update :
158
- if "system_info" in properties and "metric_stats" in properties :
161
+ if (
162
+ "system_info" in properties
163
+ and "metric_stats" in properties
164
+ and properties .get ("sdk_version_used" ) == self ._CURRENT_SDK_VERSION
165
+ ):
159
166
# cache hit
160
167
return
161
168
@@ -217,13 +224,14 @@ def generate_system_update_values():
217
224
system_update_values = {
218
225
"results" : self .results ,
219
226
# cache
227
+ "sdk_version_used" : self ._CURRENT_SDK_VERSION ,
220
228
"system_info" : sys_info .to_dict (),
221
229
"metric_stats" : binarized_metric_stats ,
222
230
"analysis_cases" : update_analysis_cases (),
223
231
}
224
232
return system_update_values
225
233
226
- def update_analysis_cases ():
234
+ def update_analysis_cases () -> dict [ str , str ] :
227
235
"""saves analysis cases to storage and returns an updated analysis_cases
228
236
dict for the DB"""
229
237
analysis_cases_lookup : dict [str , str ] = {} # level: data_path
@@ -240,16 +248,22 @@ def update_analysis_cases():
240
248
analysis_cases_lookup [analysis_level .name ] = blob_name
241
249
return analysis_cases_lookup
242
250
243
- if properties .get ("analysis_cases" ):
244
- # invalidate cache
245
- get_storage ().delete (properties ["analysis_cases" ].values ())
246
-
251
+ update_values = generate_system_update_values ()
247
252
DBUtils .update_one_by_id (
248
253
DBUtils .DEV_SYSTEM_METADATA ,
249
254
self .system_id ,
250
- generate_system_update_values () ,
255
+ update_values ,
251
256
session = session ,
252
257
)
258
+ if properties .get ("analysis_cases" ):
259
+ # remove stale data. This needs to be the last operation so it is
260
+ # protected by the transaction.
261
+ blobs_to_delete = [
262
+ blob
263
+ for blob in properties ["analysis_cases" ].values ()
264
+ if blob not in update_values ["analysis_cases" ].values ()
265
+ ]
266
+ get_storage ().delete (blobs_to_delete )
253
267
254
268
def get_raw_system_outputs (
255
269
self , output_ids : list [int ] | None , session : ClientSession | None = None
0 commit comments