33
44'use strict' ;
55
6- import { Uri } from 'vscode' ;
7- import '../../common/extensions' ;
8- import { IServiceContainer } from '../../ioc/types' ;
9- import { DEFAULT_INTERPRETER_SETTING } from '../constants' ;
10- import { DeprecatePythonPath } from '../experiments/groups' ;
11- import { IExperimentsManager , IInterpreterPathService , Resource } from '../types' ;
12-
13- type VSCodeType = typeof import ( 'vscode' ) ;
14- type CacheData = {
15- value : unknown ;
16- expiry : number ;
17- } ;
18- const resourceSpecificCacheStores = new Map < string , Map < string , CacheData > > ( ) ;
19-
20- /**
21- * Get a cache key specific to a resource (i.e. workspace)
22- * This key will be used to cache interpreter related data, hence the Python Path
23- * used in a workspace will affect the cache key.
24- * @param {Resource } resource
25- * @param {VSCodeType } [vscode=require('vscode')]
26- * @param serviceContainer
27- * @returns
28- */
29- function getCacheKey (
30- resource : Resource ,
31- vscode : VSCodeType = require ( 'vscode' ) ,
32- serviceContainer : IServiceContainer | undefined ,
33- ) {
34- const section = vscode . workspace . getConfiguration ( 'python' , vscode . Uri . file ( __filename ) ) ;
35- if ( ! section ) {
36- return 'python' ;
37- }
38- let interpreterPathService : IInterpreterPathService | undefined ;
39- let inExperiment : boolean | undefined ;
40- if ( serviceContainer ) {
41- interpreterPathService = serviceContainer . get < IInterpreterPathService > ( IInterpreterPathService ) ;
42- const abExperiments = serviceContainer . get < IExperimentsManager > ( IExperimentsManager ) ;
43- inExperiment = abExperiments . inExperiment ( DeprecatePythonPath . experiment ) ;
44- abExperiments . sendTelemetryIfInExperiment ( DeprecatePythonPath . control ) ;
45- }
46- const globalPythonPath =
47- inExperiment && interpreterPathService
48- ? interpreterPathService . inspect ( vscode . Uri . file ( __filename ) ) . globalValue || DEFAULT_INTERPRETER_SETTING
49- : section . inspect < string > ( 'pythonPath' ) ! . globalValue || DEFAULT_INTERPRETER_SETTING ;
50- // Get the workspace related to this resource.
51- if (
52- ! resource ||
53- ! Array . isArray ( vscode . workspace . workspaceFolders ) ||
54- vscode . workspace . workspaceFolders . length === 0
55- ) {
56- return globalPythonPath ;
57- }
58- const folder = resource ? vscode . workspace . getWorkspaceFolder ( resource ) : vscode . workspace . workspaceFolders [ 0 ] ;
59- if ( ! folder ) {
60- return globalPythonPath ;
61- }
62- const workspacePythonPath =
63- inExperiment && interpreterPathService
64- ? interpreterPathService . get ( resource )
65- : vscode . workspace . getConfiguration ( 'python' , resource ) . get < string > ( 'pythonPath' ) ||
66- DEFAULT_INTERPRETER_SETTING ;
67- return `${ folder . uri . fsPath } -${ workspacePythonPath } ` ;
68- }
69- /**
70- * Gets the cache store for a resource that's specific to the interpreter.
71- * @param {Resource } resource
72- * @param {VSCodeType } [vscode=require('vscode')]
73- * @param serviceContainer
74- * @returns
75- */
76- function getCacheStore (
77- resource : Resource ,
78- vscode : VSCodeType = require ( 'vscode' ) ,
79- serviceContainer : IServiceContainer | undefined ,
80- ) {
81- const key = getCacheKey ( resource , vscode , serviceContainer ) ;
82- if ( ! resourceSpecificCacheStores . has ( key ) ) {
83- resourceSpecificCacheStores . set ( key , new Map < string , CacheData > ( ) ) ;
84- }
85- return resourceSpecificCacheStores . get ( key ) ! ;
86- }
87-
886const globalCacheStore = new Map < string , { expiry : number ; data : any } > ( ) ;
897
908/**
@@ -103,18 +21,23 @@ export function getCacheKeyFromFunctionArgs(keyPrefix: string, fnArgs: any[]): s
10321
10422export function clearCache ( ) {
10523 globalCacheStore . clear ( ) ;
106- resourceSpecificCacheStores . clear ( ) ;
10724}
10825
26+ type CacheData < T > = {
27+ value : T ;
28+ expiry : number ;
29+ } ;
30+
31+ /**
32+ * InMemoryCache caches a single value up until its expiry.
33+ */
10934export class InMemoryCache < T > {
110- private readonly _store = new Map < string , CacheData > ( ) ;
111- protected get store ( ) : Map < string , CacheData > {
112- return this . _store ;
113- }
114- constructor ( protected readonly expiryDurationMs : number , protected readonly cacheKey : string = '' ) { }
35+ private cacheData ?: CacheData < T > ;
36+
37+ constructor ( protected readonly expiryDurationMs : number ) { }
11538 public get hasData ( ) {
116- if ( ! this . store . get ( this . cacheKey ) || this . hasExpired ( this . store . get ( this . cacheKey ) ! . expiry ) ) {
117- this . store . delete ( this . cacheKey ) ;
39+ if ( ! this . cacheData || this . hasExpired ( this . cacheData . expiry ) ) {
40+ this . cacheData = undefined ;
11841 return false ;
11942 }
12043 return true ;
@@ -128,19 +51,23 @@ export class InMemoryCache<T> {
12851 * @memberof InMemoryCache
12952 */
13053 public get data ( ) : T | undefined {
131- if ( ! this . hasData || ! this . store . has ( this . cacheKey ) ) {
54+ if ( ! this . hasData ) {
13255 return ;
13356 }
134- return this . store . get ( this . cacheKey ) ?. value as T ;
57+ return this . cacheData ?. value ;
13558 }
13659 public set data ( value : T | undefined ) {
137- this . store . set ( this . cacheKey , {
138- expiry : this . calculateExpiry ( ) ,
139- value,
140- } ) ;
60+ if ( value !== undefined ) {
61+ this . cacheData = {
62+ expiry : this . calculateExpiry ( ) ,
63+ value,
64+ } ;
65+ } else {
66+ this . cacheData = undefined ;
67+ }
14168 }
14269 public clear ( ) {
143- this . store . clear ( ) ;
70+ this . cacheData = undefined ;
14471 }
14572
14673 /**
@@ -164,20 +91,3 @@ export class InMemoryCache<T> {
16491 return Date . now ( ) + this . expiryDurationMs ;
16592 }
16693}
167-
168- export class InMemoryInterpreterSpecificCache < T > extends InMemoryCache < T > {
169- private readonly resource : Resource ;
170- protected get store ( ) {
171- return getCacheStore ( this . resource , this . vscode , this . serviceContainer ) ;
172- }
173- constructor (
174- keyPrefix : string ,
175- expiryDurationMs : number ,
176- args : [ Uri | undefined , ...any [ ] ] ,
177- private readonly serviceContainer : IServiceContainer | undefined ,
178- private readonly vscode : VSCodeType = require ( 'vscode' ) ,
179- ) {
180- super ( expiryDurationMs , getCacheKeyFromFunctionArgs ( keyPrefix , args . slice ( 1 ) ) ) ;
181- this . resource = args [ 0 ] ;
182- }
183- }
0 commit comments