@@ -36,17 +36,22 @@ def profiling(page: int) -> Union[str, werkzeug.wrappers.Response]:
3636 if page < 1 :
3737 return redirect (url_for ('admin.profiling' , page = 1 , ** request .args ))
3838 prof_dir = _cfg ('profile-dir' )
39- profilings = [] if not prof_dir else list (map (
40- parse_prof_filename ,
41- sorted (Path (prof_dir ).glob ('*.prof' ),
42- key = lambda p : - p .stat ().st_mtime )))
39+ # this directory can hold a huge number of profile files, so do as little
40+ # per file as possible sort on the timestamp that's already in the
41+ # filename (no stat() per file) and on ly parse the page we actually show.
42+ # The old code stat()'d and parsed every file on every load which made
43+ # opening the admin panel hang and tie up workers
44+ files = sorted (Path (prof_dir ).glob ('*.prof' ),
45+ key = lambda p : p .name .split ('.' )[- 2 ],
46+ reverse = True ) if prof_dir else []
4347 query = request .args .get ('query' , type = str )
4448 if query :
4549 terms = query .split (' ' )
46- profilings = [p for p in profilings
47- if all (map (lambda t : query_term_matches (t , p ), terms ))]
48- total_pages = max (1 , math .ceil (len (profilings ) / ITEMS_PER_PAGE ))
49- profilings = profilings [(page - 1 ) * ITEMS_PER_PAGE : page * ITEMS_PER_PAGE ]
50+ files = [f for f in files
51+ if all (query_term_matches (t , parse_prof_filename (f )) for t in terms )]
52+ total_pages = max (1 , math .ceil (len (files ) / ITEMS_PER_PAGE ))
53+ page_files = files [(page - 1 ) * ITEMS_PER_PAGE : page * ITEMS_PER_PAGE ]
54+ profilings = [parse_prof_filename (f ) for f in page_files ]
5055 return render_template ("admin-profiling.html" ,
5156 profilings = profilings , query = query ,
5257 page = page , total_pages = total_pages )
0 commit comments