1
+ from collections import (
2
+ defaultdict ,
3
+ )
4
+ from functools import _make_key # type: ignore
5
+ from functools import lru_cache
6
+ from threading import (
7
+ RLock ,
8
+ )
1
9
from typing import (
2
10
Any ,
11
+ Callable ,
3
12
)
4
13
5
14
from eth_typing import (
13
22
)
14
23
15
24
25
+ def thread_safe_lru (func : Callable [..., Any ]) -> Callable [..., Any ]:
26
+ """
27
+ A thread-safe cache decorator that prevents concurrent invocations
28
+ and allow reusing from cache.
29
+ """
30
+ caching_func = lru_cache (maxsize = 8 , typed = False )(func )
31
+ _keyed_locks = defaultdict (RLock ) # type: ignore
32
+
33
+ def inner (* args : Any , ** kwargs : Any ) -> Callable [..., Any ]:
34
+ key = _make_key (args , kwargs , typed = False )
35
+ with _keyed_locks [key ]:
36
+ return caching_func (* args , ** kwargs )
37
+ return inner
38
+
39
+
40
+ @thread_safe_lru
16
41
def cache_session (endpoint_uri : URI , session : requests .Session ) -> None :
17
42
cache_key = generate_cache_key (endpoint_uri )
18
43
_session_cache [cache_key ] = session
@@ -32,6 +57,7 @@ def _get_session(endpoint_uri: URI) -> requests.Session:
32
57
return _session_cache [cache_key ]
33
58
34
59
60
+ @thread_safe_lru
35
61
def make_post_request (endpoint_uri : URI , data : bytes , * args : Any , ** kwargs : Any ) -> bytes :
36
62
kwargs .setdefault ('timeout' , 10 )
37
63
session = _get_session (endpoint_uri )
0 commit comments