@@ -5,79 +5,48 @@ import { inject, injectable } from 'inversify';
55import * as path from 'path' ;
66import { Uri } from 'vscode' ;
77import { IApplicationShell , IWorkspaceService } from '../../../common/application/types' ;
8- import { createDeferred , Deferred } from '../../../common/helpers' ;
98import { IFileSystem } from '../../../common/platform/types' ;
109import { IProcessService } from '../../../common/process/types' ;
1110import { getPythonExecutable } from '../../../debugger/Common/Utils' ;
1211import { IServiceContainer } from '../../../ioc/types' ;
13- import { IInterpreterLocatorService , IInterpreterVersionService , InterpreterType , PythonInterpreter } from '../../contracts' ;
12+ import { IInterpreterVersionService , InterpreterType , PythonInterpreter } from '../../contracts' ;
13+ import { CacheableLocatorService } from './cacheableLocatorService' ;
1414
1515const execName = 'pipenv' ;
16- const CACHE_TIMEOUT = 2000 ;
1716
1817@injectable ( )
19- export class PipEnvService implements IInterpreterLocatorService {
18+ export class PipEnvService extends CacheableLocatorService {
2019 private readonly versionService : IInterpreterVersionService ;
2120 private readonly process : IProcessService ;
2221 private readonly workspace : IWorkspaceService ;
2322 private readonly fs : IFileSystem ;
2423
25- private pendingPromises : Deferred < PythonInterpreter [ ] > [ ] = [ ] ;
26- private readonly cachedInterpreters = new Map < string , PythonInterpreter > ( ) ;
27-
28- constructor ( @inject ( IServiceContainer ) private serviceContainer : IServiceContainer ) {
24+ constructor ( @inject ( IServiceContainer ) serviceContainer : IServiceContainer ) {
25+ super ( 'PipEnvService' , serviceContainer ) ;
2926 this . versionService = this . serviceContainer . get < IInterpreterVersionService > ( IInterpreterVersionService ) ;
3027 this . process = this . serviceContainer . get < IProcessService > ( IProcessService ) ;
3128 this . workspace = this . serviceContainer . get < IWorkspaceService > ( IWorkspaceService ) ;
3229 this . fs = this . serviceContainer . get < IFileSystem > ( IFileSystem ) ;
3330 }
34-
35- public getInterpreters ( resource ?: Uri ) : Promise < PythonInterpreter [ ] > {
31+ // tslint:disable-next-line:no-empty
32+ public dispose ( ) { }
33+ protected getInterpretersImplementation ( resource ?: Uri ) : Promise < PythonInterpreter [ ] > {
3634 const pipenvCwd = this . getPipenvWorkingDirectory ( resource ) ;
3735 if ( ! pipenvCwd ) {
3836 return Promise . resolve ( [ ] ) ;
3937 }
4038
41- // Try cache first
42- const interpreter = this . cachedInterpreters [ pipenvCwd ] ;
43- if ( interpreter ) {
44- return Promise . resolve ( [ interpreter ] ) ;
45- }
46- // We don't want multiple requests executing pipenv
47- const deferred = createDeferred < PythonInterpreter [ ] > ( ) ;
48- this . pendingPromises . push ( deferred ) ;
49- if ( this . pendingPromises . length === 1 ) {
50- // First call, start worker
51- this . getInterpreter ( pipenvCwd )
52- . then ( x => this . resolveDeferred ( x ? [ x ] : [ ] ) )
53- . catch ( e => this . resolveDeferred ( [ ] ) ) ;
54- }
55- return deferred . promise ;
56- }
57-
58- public dispose ( ) {
59- this . resolveDeferred ( [ ] ) ;
60- }
61-
62- private resolveDeferred ( result : PythonInterpreter [ ] ) {
63- this . pendingPromises . forEach ( p => p . resolve ( result ) ) ;
64- this . pendingPromises = [ ] ;
65- }
66-
67- private async getInterpreter ( pipenvCwd : string ) : Promise < PythonInterpreter | undefined > {
68- const interpreter = await this . getInterpreterFromPipenv ( pipenvCwd ) ;
69- if ( interpreter ) {
70- this . cachedInterpreters [ pipenvCwd ] = interpreter ;
71- setTimeout ( ( ) => this . cachedInterpreters . clear ( ) , CACHE_TIMEOUT ) ;
72- }
73- return interpreter ;
39+ return this . getInterpreterFromPipenv ( pipenvCwd )
40+ . then ( item => item ? [ item ] : [ ] )
41+ . catch ( ( ) => [ ] ) ;
7442 }
7543
7644 private async getInterpreterFromPipenv ( pipenvCwd : string ) : Promise < PythonInterpreter | undefined > {
7745 const interpreterPath = await this . getInterpreterPathFromPipenv ( pipenvCwd ) ;
7846 if ( ! interpreterPath ) {
7947 return ;
8048 }
49+
8150 const pythonExecutablePath = getPythonExecutable ( interpreterPath ) ;
8251 const ver = await this . versionService . getVersion ( pythonExecutablePath , '' ) ;
8352 return {
0 commit comments