@@ -13,9 +13,9 @@ Specs: https://jupyter-client.readthedocs.io/en/stable/kernels.html#kernel-specs
13
13
14
14
import { findAll } from "kernelspecs" ;
15
15
import LRU from "lru-cache" ;
16
-
17
16
import type { KernelSpec } from "@cocalc/jupyter/types/types" ;
18
17
import { field_cmp } from "@cocalc/util/misc" ;
18
+ import { reuseInFlight } from "@cocalc/util/reuse-in-flight" ;
19
19
20
20
const cache = new LRU < "kernel_data" , KernelSpec [ ] > ( {
21
21
ttl : 15 * 1000 ,
@@ -44,35 +44,39 @@ function spec2language(spec): string {
44
44
}
45
45
}
46
46
47
- export async function get_kernel_data ( ) : Promise < KernelSpec [ ] > {
48
- let x = cache . get ( "kernel_data" ) ;
49
- if ( x != null ) {
50
- return x ;
51
- }
52
- const kernel_data = await findAll ( ) ;
53
- const v : KernelSpec [ ] = [ ] ;
54
- for ( const kernel in kernel_data ) {
55
- const value = kernel_data [ kernel ] ;
56
- v . push ( {
57
- name : kernel . toLowerCase ( ) ,
58
- display_name : value . spec . display_name ,
59
- language : spec2language ( value . spec ) ,
60
- // @ts -ignore
61
- interrupt_mode : value . spec . interrupt_mode ,
62
- env : value . spec . env ?? { } ,
63
- // @ts -ignore
64
- metadata : value . spec . metadata ,
65
- // kernelspecs incorrectly calls it resources_dir instead of resource_dir.
66
- // See https://github.com/nteract/kernelspecs/issues/25
67
- // @ts -ignore
68
- resource_dir : value . resource_dir ?? value . resources_dir ,
69
- argv : value . spec . argv ,
70
- } ) ;
71
- }
72
- v . sort ( field_cmp ( "display_name" ) ) ;
73
- cache . set ( "kernel_data" , v ) ;
74
- return v ;
75
- }
47
+ // this is very expensive and can get called many times at once before
48
+ // the cache is set, which is very bad... so reuseInFlight.
49
+ export const get_kernel_data = reuseInFlight (
50
+ async ( ) : Promise < KernelSpec [ ] > => {
51
+ let x = cache . get ( "kernel_data" ) ;
52
+ if ( x != null ) {
53
+ return x ;
54
+ }
55
+ const kernel_data = await findAll ( ) ;
56
+ const v : KernelSpec [ ] = [ ] ;
57
+ for ( const kernel in kernel_data ) {
58
+ const value = kernel_data [ kernel ] ;
59
+ v . push ( {
60
+ name : kernel . toLowerCase ( ) ,
61
+ display_name : value . spec . display_name ,
62
+ language : spec2language ( value . spec ) ,
63
+ // @ts -ignore
64
+ interrupt_mode : value . spec . interrupt_mode ,
65
+ env : value . spec . env ?? { } ,
66
+ // @ts -ignore
67
+ metadata : value . spec . metadata ,
68
+ // kernelspecs incorrectly calls it resources_dir instead of resource_dir.
69
+ // See https://github.com/nteract/kernelspecs/issues/25
70
+ // @ts -ignore
71
+ resource_dir : value . resource_dir ?? value . resources_dir ,
72
+ argv : value . spec . argv ,
73
+ } ) ;
74
+ }
75
+ v . sort ( field_cmp ( "display_name" ) ) ;
76
+ cache . set ( "kernel_data" , v ) ;
77
+ return v ;
78
+ } ,
79
+ ) ;
76
80
77
81
export async function getLanguage ( kernelName : string ) : Promise < string > {
78
82
const kernelSpec = await get_kernel_data_by_name ( kernelName ) ;
0 commit comments