22// Licensed under the MIT License.
33
44import { injectable } from 'inversify' ;
5- import { EnvironmentType , PythonEnvironment } from '.' ;
5+ import { createDeferred , Deferred } from '../../common/utils/async ' ;
66import { createWorkerPool , IWorkerPool , QueuePosition } from '../../common/utils/workerPool' ;
7+ import { getInterpreterInfo , InterpreterInformation } from '../base/info/interpreter' ;
78import { shellExecute } from '../common/externalDependencies' ;
89import { buildPythonExecInfo } from '../exec' ;
9- import { getInterpreterInfo } from './interpreter' ;
1010
1111export enum EnvironmentInfoServiceQueuePriority {
1212 Default ,
@@ -18,37 +18,17 @@ export interface IEnvironmentInfoService {
1818 getEnvironmentInfo (
1919 interpreterPath : string ,
2020 priority ?: EnvironmentInfoServiceQueuePriority
21- ) : Promise < PythonEnvironment | undefined > ;
21+ ) : Promise < InterpreterInformation | undefined > ;
2222}
2323
24- async function buildEnvironmentInfo ( interpreterPath : string ) : Promise < PythonEnvironment | undefined > {
25- const interpreterInfo = await getInterpreterInfo ( buildPythonExecInfo ( interpreterPath ) , shellExecute ) ;
24+ async function buildEnvironmentInfo ( interpreterPath : string ) : Promise < InterpreterInformation | undefined > {
25+ const interpreterInfo = await getInterpreterInfo ( buildPythonExecInfo ( interpreterPath ) , shellExecute ) . catch (
26+ ( ) => undefined ,
27+ ) ;
2628 if ( interpreterInfo === undefined || interpreterInfo . version === undefined ) {
2729 return undefined ;
2830 }
29- return {
30- path : interpreterInfo . path ,
31- // Have to do this because the type returned by getInterpreterInfo is SemVer
32- // But we expect this to be PythonVersion
33- version : {
34- raw : interpreterInfo . version . raw ,
35- major : interpreterInfo . version . major ,
36- minor : interpreterInfo . version . minor ,
37- patch : interpreterInfo . version . patch ,
38- build : interpreterInfo . version . build ,
39- prerelease : interpreterInfo . version . prerelease ,
40- } ,
41- sysVersion : interpreterInfo . sysVersion ,
42- architecture : interpreterInfo . architecture ,
43- sysPrefix : interpreterInfo . sysPrefix ,
44- pipEnvWorkspaceFolder : interpreterInfo . pipEnvWorkspaceFolder ,
45- companyDisplayName : '' ,
46- displayName : '' ,
47- envType : EnvironmentType . Unknown , // Code to handle This will be added later.
48- envName : '' ,
49- envPath : '' ,
50- cachedEntry : false ,
51- } ;
31+ return interpreterInfo ;
5232}
5333
5434@injectable ( )
@@ -57,29 +37,35 @@ export class EnvironmentInfoService implements IEnvironmentInfoService {
5737 // path again and again in a given session. This information will likely not change in a given
5838 // session. There are definitely cases where this will change. But a simple reload should address
5939 // those.
60- private readonly cache : Map < string , PythonEnvironment > = new Map < string , PythonEnvironment > ( ) ;
40+ private readonly cache : Map < string , Deferred < InterpreterInformation > > = new Map <
41+ string ,
42+ Deferred < InterpreterInformation >
43+ > ( ) ;
6144
62- private readonly workerPool : IWorkerPool < string , PythonEnvironment | undefined > ;
45+ private readonly workerPool : IWorkerPool < string , InterpreterInformation | undefined > ;
6346
6447 public constructor ( ) {
65- this . workerPool = createWorkerPool < string , PythonEnvironment | undefined > ( buildEnvironmentInfo ) ;
48+ this . workerPool = createWorkerPool < string , InterpreterInformation | undefined > ( buildEnvironmentInfo ) ;
6649 }
6750
6851 public async getEnvironmentInfo (
6952 interpreterPath : string ,
7053 priority ?: EnvironmentInfoServiceQueuePriority ,
71- ) : Promise < PythonEnvironment | undefined > {
54+ ) : Promise < InterpreterInformation | undefined > {
7255 const result = this . cache . get ( interpreterPath ) ;
7356 if ( result !== undefined ) {
74- return result ;
57+ // Another call for this environment has already been made, return its result
58+ return result . promise ;
7559 }
76-
60+ const deferred = createDeferred < InterpreterInformation > ( ) ;
61+ this . cache . set ( interpreterPath , deferred ) ;
7762 return ( priority === EnvironmentInfoServiceQueuePriority . High
7863 ? this . workerPool . addToQueue ( interpreterPath , QueuePosition . Front )
7964 : this . workerPool . addToQueue ( interpreterPath , QueuePosition . Back )
8065 ) . then ( ( r ) => {
81- if ( r !== undefined ) {
82- this . cache . set ( interpreterPath , r ) ;
66+ deferred . resolve ( r ) ;
67+ if ( r === undefined ) {
68+ this . cache . delete ( interpreterPath ) ;
8369 }
8470 return r ;
8571 } ) ;
0 commit comments