4141)
4242from pygls .workspace import TextDocument
4343
44+ from .constants import MAX_CONCURRENT_DEBOUNCE_CALLS
4445from .initialization_options import HoverDisableOptions , InitializationOptions
4546from .type_map import get_lsp_completion_type , get_lsp_symbol_type
4647
5354P = ParamSpec ("P" )
5455
5556
57+ _debounce_semaphore = threading .Semaphore (MAX_CONCURRENT_DEBOUNCE_CALLS )
58+
59+
5660def debounce (
57- interval_s : int , keyed_by : Optional [str ] = None
61+ interval_s : float , keyed_by : Optional [str ] = None
5862) -> Callable [[Callable [P , None ]], Callable [P , None ]]:
5963 """Debounce calls to this function until interval_s seconds have passed.
6064
61- Decorator copied from https://github.com/python-lsp/python-lsp-
62- server
65+ Decorator adapted from https://github.com/python-lsp/python-lsp-server
6366 """
6467
6568 def wrapper (func : Callable [P , None ]) -> Callable [P , None ]:
@@ -68,20 +71,23 @@ def wrapper(func: Callable[P, None]) -> Callable[P, None]:
6871
6972 @functools .wraps (func )
7073 def debounced (* args : P .args , ** kwargs : P .kwargs ) -> None :
74+ _debounce_semaphore .acquire ()
75+
7176 sig = inspect .signature (func )
7277 call_args = sig .bind (* args , ** kwargs )
7378 key = call_args .arguments [keyed_by ] if keyed_by else None
7479
7580 def run () -> None :
7681 with lock :
7782 del timers [key ]
78- return func (* args , ** kwargs )
83+ func (* args , ** kwargs )
84+ _debounce_semaphore .release ()
7985
8086 with lock :
8187 old_timer = timers .get (key )
8288 if old_timer :
8389 old_timer .cancel ()
84-
90+ _debounce_semaphore . release ()
8591 timer = threading .Timer (interval_s , run )
8692 timers [key ] = timer
8793 timer .start ()
0 commit comments