@@ -38,6 +38,12 @@ class InvalidRangeError(Exception):
3838_T = TypeVar ("_T" )
3939
4040
41+ class CacheEntry :
42+ def __init__ (self , data : Any = None ) -> None :
43+ self .data = data
44+ self .lock : asyncio .Lock = asyncio .Lock ()
45+
46+
4147class TextDocument :
4248 def __init__ (
4349 self ,
@@ -73,7 +79,7 @@ def __init__(
7379
7480 self ._lines : Optional [List [str ]] = None
7581
76- self ._cache : Dict [weakref .ref [Any ], Any ] = {}
82+ self ._cache : Dict [weakref .ref [Any ], CacheEntry ] = {}
7783 self ._in_change_cache = False
7884
7985 self ._data : weakref .WeakKeyDictionary [Any , Any ] = weakref .WeakKeyDictionary ()
@@ -170,23 +176,6 @@ async def invalidate_data(self) -> None:
170176 async with self ._lock :
171177 self ._invalidate_data ()
172178
173- async def get_cache (
174- self ,
175- entry : Union [Callable [[TextDocument ], Awaitable [_T ]], Callable [..., Awaitable [_T ]]],
176- * args : Any ,
177- ** kwargs : Any ,
178- ) -> _T :
179- if self ._in_change_cache :
180- return await self ._get_cache (entry , * args , ** kwargs )
181-
182- else :
183- self ._in_change_cache = True
184- try :
185- async with self ._lock :
186- return await self ._get_cache (entry , * args , ** kwargs )
187- finally :
188- self ._in_change_cache = False
189-
190179 async def __remove_cache_entry_safe (self , ref : Any ) -> None :
191180 async with self ._lock :
192181 self ._cache .pop (ref )
@@ -206,7 +195,7 @@ def __get_cache_reference(self, entry: Callable[..., Any]) -> weakref.ref[Any]:
206195
207196 return reference
208197
209- async def _get_cache (
198+ async def get_cache (
210199 self ,
211200 entry : Union [Callable [[TextDocument ], Awaitable [_T ]], Callable [..., Awaitable [_T ]]],
212201 * args : Any ,
@@ -216,42 +205,21 @@ async def _get_cache(
216205 reference = self .__get_cache_reference (entry )
217206
218207 if reference not in self ._cache :
219- self ._cache [reference ] = None
208+ async with self ._lock :
209+ self ._cache [reference ] = CacheEntry ()
220210
221- if self ._cache [reference ] is None :
222- result = entry (self , * args , ** kwargs ) # type: ignore
211+ e = self ._cache [reference ]
223212
224- if isinstance (result , Awaitable ):
225- self ._cache [reference ] = await result
226- else :
227- self ._cache [reference ] = result
228-
229- return cast ("_T" , self ._cache [reference ])
230-
231- async def set_cache (
232- self ,
233- entry : Union [Callable [[TextDocument ], Awaitable [_T ]], Callable [..., Awaitable [_T ]]],
234- data : _T ,
235- ) -> _T :
236- if self ._in_change_cache :
237- return await self ._set_cache (entry , data )
238-
239- else :
240- self ._in_change_cache = True
241- try :
242- async with self ._lock :
243- return await self ._set_cache (entry , data )
244- finally :
245- self ._in_change_cache = False
246-
247- async def _set_cache (
248- self , entry : Union [Callable [[TextDocument ], Awaitable [_T ]], Callable [..., Awaitable [_T ]]], data : _T
249- ) -> _T :
250- reference = self .__get_cache_reference (entry )
213+ async with e .lock :
214+ if e .data is None :
215+ result = entry (self , * args , ** kwargs ) # type: ignore
251216
252- self ._cache [reference ] = data
217+ if isinstance (result , Awaitable ):
218+ e .data = await result
219+ else :
220+ e .data = result
253221
254- return data
222+ return cast ( "_T" , e . data )
255223
256224 async def remove_cache_entry (
257225 self , entry : Union [Callable [[TextDocument ], Awaitable [_T ]], Callable [..., Awaitable [_T ]]]
0 commit comments