@@ -5,79 +5,48 @@ import { inject, injectable } from 'inversify';
5
5
import * as path from 'path' ;
6
6
import { Uri } from 'vscode' ;
7
7
import { IApplicationShell , IWorkspaceService } from '../../../common/application/types' ;
8
- import { createDeferred , Deferred } from '../../../common/helpers' ;
9
8
import { IFileSystem } from '../../../common/platform/types' ;
10
9
import { IProcessService } from '../../../common/process/types' ;
11
10
import { getPythonExecutable } from '../../../debugger/Common/Utils' ;
12
11
import { IServiceContainer } from '../../../ioc/types' ;
13
- import { IInterpreterLocatorService , IInterpreterVersionService , InterpreterType , PythonInterpreter } from '../../contracts' ;
12
+ import { IInterpreterVersionService , InterpreterType , PythonInterpreter } from '../../contracts' ;
13
+ import { CacheableLocatorService } from './cacheableLocatorService' ;
14
14
15
15
const execName = 'pipenv' ;
16
- const CACHE_TIMEOUT = 2000 ;
17
16
18
17
@injectable ( )
19
- export class PipEnvService implements IInterpreterLocatorService {
18
+ export class PipEnvService extends CacheableLocatorService {
20
19
private readonly versionService : IInterpreterVersionService ;
21
20
private readonly process : IProcessService ;
22
21
private readonly workspace : IWorkspaceService ;
23
22
private readonly fs : IFileSystem ;
24
23
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 ) ;
29
26
this . versionService = this . serviceContainer . get < IInterpreterVersionService > ( IInterpreterVersionService ) ;
30
27
this . process = this . serviceContainer . get < IProcessService > ( IProcessService ) ;
31
28
this . workspace = this . serviceContainer . get < IWorkspaceService > ( IWorkspaceService ) ;
32
29
this . fs = this . serviceContainer . get < IFileSystem > ( IFileSystem ) ;
33
30
}
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 [ ] > {
36
34
const pipenvCwd = this . getPipenvWorkingDirectory ( resource ) ;
37
35
if ( ! pipenvCwd ) {
38
36
return Promise . resolve ( [ ] ) ;
39
37
}
40
38
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 ( ( ) => [ ] ) ;
74
42
}
75
43
76
44
private async getInterpreterFromPipenv ( pipenvCwd : string ) : Promise < PythonInterpreter | undefined > {
77
45
const interpreterPath = await this . getInterpreterPathFromPipenv ( pipenvCwd ) ;
78
46
if ( ! interpreterPath ) {
79
47
return ;
80
48
}
49
+
81
50
const pythonExecutablePath = getPythonExecutable ( interpreterPath ) ;
82
51
const ver = await this . versionService . getVersion ( pythonExecutablePath , '' ) ;
83
52
return {
0 commit comments