Skip to content

Commit b478ae3

Browse files
committed
refactor(langserver): remove threaded decorator from rpc methods and introduce a threaded property for the rpc_method decorator
1 parent 660d8f9 commit b478ae3

27 files changed

+86
-172
lines changed

packages/jsonrpc2/src/robotcode/jsonrpc2/protocol.py

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,8 @@
3232
runtime_checkable,
3333
)
3434

35-
from robotcode.core.async_tools import create_sub_task, run_coroutine_in_thread
36-
from robotcode.core.concurrent import (
37-
FutureEx,
38-
is_threaded_callable,
39-
run_in_thread,
40-
)
35+
from robotcode.core.async_tools import run_coroutine_in_thread
36+
from robotcode.core.concurrent import FutureEx, run_in_thread
4137
from robotcode.core.event import event
4238
from robotcode.core.utils.dataclasses import as_json, from_dict
4339
from robotcode.core.utils.inspect import ensure_coroutine, iter_methods
@@ -150,6 +146,7 @@ class RpcMethodEntry:
150146
method: Callable[..., Any]
151147
param_type: Optional[Type[Any]]
152148
cancelable: bool
149+
threaded: bool
153150

154151
_is_coroutine: Optional[bool] = field(default=None, init=False)
155152

@@ -181,6 +178,7 @@ def rpc_method(
181178
name: Optional[str] = None,
182179
param_type: Optional[Type[Any]] = None,
183180
cancelable: bool = True,
181+
threaded: bool = False,
184182
) -> Callable[[_F], _F]:
185183
...
186184

@@ -191,6 +189,7 @@ def rpc_method(
191189
name: Optional[str] = None,
192190
param_type: Optional[Type[Any]] = None,
193191
cancelable: bool = True,
192+
threaded: bool = False,
194193
) -> Callable[[_F], _F]:
195194
def _decorator(func: _F) -> Callable[[_F], _F]:
196195
if inspect.isclass(_func):
@@ -207,7 +206,7 @@ def _decorator(func: _F) -> Callable[[_F], _F]:
207206
if real_name is None or not real_name:
208207
raise ValueError("name is empty.")
209208

210-
cast(RpcMethod, f).__rpc_method__ = RpcMethodEntry(real_name, f, param_type, cancelable)
209+
cast(RpcMethod, f).__rpc_method__ = RpcMethodEntry(real_name, f, param_type, cancelable, threaded)
211210
return func
212211

213212
if _func is None:
@@ -274,6 +273,7 @@ def get_methods(obj: Any) -> Dict[str, RpcMethodEntry]:
274273
method,
275274
rpc_method.__rpc_method__.param_type,
276275
rpc_method.__rpc_method__.cancelable,
276+
rpc_method.__rpc_method__.threaded,
277277
)
278278
for method, rpc_method in map(
279279
lambda m1: (m1, cast(RpcMethod, m1)),
@@ -324,10 +324,11 @@ def add_method(
324324
func: Callable[..., Any],
325325
param_type: Optional[Type[Any]] = None,
326326
cancelable: bool = True,
327+
threaded: bool = False,
327328
) -> None:
328329
self.__ensure_initialized()
329330

330-
self.__methods[name] = RpcMethodEntry(name, func, param_type, cancelable)
331+
self.__methods[name] = RpcMethodEntry(name, func, param_type, cancelable, threaded)
331332

332333
def remove_method(self, name: str) -> Optional[RpcMethodEntry]:
333334
self.__ensure_initialized()
@@ -741,12 +742,10 @@ async def handle_request(self, message: JsonRPCRequest) -> None:
741742

742743
params = self._convert_params(e.method, e.param_type, message.params)
743744

744-
is_threaded_method = is_threaded_callable(e.method)
745-
746-
if not is_threaded_method and not e.is_coroutine:
745+
if not e.threaded and not e.is_coroutine:
747746
self.send_response(message.id, e.method(*params[0], **params[1]))
748747
else:
749-
if is_threaded_method:
748+
if e.threaded:
750749
if e.is_coroutine:
751750
task = run_coroutine_in_thread(
752751
ensure_coroutine(cast(Callable[..., Any], e.method)),
@@ -756,10 +755,7 @@ async def handle_request(self, message: JsonRPCRequest) -> None:
756755
else:
757756
task = asyncio.wrap_future(run_in_thread(e.method, *params[0], **params[1]))
758757
else:
759-
task = create_sub_task(
760-
ensure_coroutine(e.method)(*params[0], **params[1]),
761-
name=message.method,
762-
)
758+
task = asyncio.create_task(e.method(*params[0], **params[1]), name=message.method)
763759

764760
with self._received_request_lock:
765761
self._received_request[message.id] = ReceivedRequestEntry(task, message, e.cancelable)
@@ -845,20 +841,18 @@ async def handle_notification(self, message: JsonRPCNotification) -> None:
845841
try:
846842
params = self._convert_params(e.method, e.param_type, message.params)
847843

848-
if not e.is_coroutine:
844+
if not e.threaded and not e.is_coroutine:
849845
e.method(*params[0], **params[1])
850846
else:
851-
if is_threaded_callable(e.method):
852-
task = run_coroutine_in_thread(
853-
ensure_coroutine(cast(Callable[..., Any], e.method)),
854-
*params[0],
855-
**params[1],
856-
)
847+
if e.threaded:
848+
if e.is_coroutine:
849+
task = run_coroutine_in_thread(
850+
ensure_coroutine(cast(Callable[..., Any], e.method)), *params[0], **params[1]
851+
)
852+
else:
853+
task = asyncio.wrap_future(run_in_thread(e.method, *params[0], **params[1]))
857854
else:
858-
task = create_sub_task(
859-
ensure_coroutine(e.method)(*params[0], **params[1]),
860-
name=message.method,
861-
)
855+
task = asyncio.create_task(e.method(*params[0], **params[1]), name=message.method)
862856

863857
await task
864858
except asyncio.CancelledError:

packages/language_server/src/robotcode/language_server/common/parts/code_action.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from itertools import chain
33
from typing import TYPE_CHECKING, Any, Final, List, Optional, Union, cast
44

5-
from robotcode.core.concurrent import check_current_thread_canceled, threaded
5+
from robotcode.core.concurrent import check_current_thread_canceled
66
from robotcode.core.event import event
77
from robotcode.core.lsp.types import (
88
CodeAction,
@@ -66,8 +66,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None:
6666
resolve_provider=len(self.resolve) > 0,
6767
)
6868

69-
@rpc_method(name="textDocument/codeAction", param_type=CodeActionParams)
70-
@threaded
69+
@rpc_method(name="textDocument/codeAction", param_type=CodeActionParams, threaded=True)
7170
def _text_document_code_action(
7271
self,
7372
text_document: TextDocumentIdentifier,
@@ -109,8 +108,7 @@ def _text_document_code_action(
109108

110109
return results
111110

112-
@rpc_method(name="codeAction/resolve", param_type=CodeAction)
113-
@threaded
111+
@rpc_method(name="codeAction/resolve", param_type=CodeAction, threaded=True)
114112
def _text_document_code_action_resolve(self, params: CodeAction, *args: Any, **kwargs: Any) -> CodeAction:
115113
results: List[CodeAction] = []
116114

packages/language_server/src/robotcode/language_server/common/parts/code_lens.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
from concurrent.futures import CancelledError
22
from typing import TYPE_CHECKING, Any, Final, List, Optional
33

4-
from robotcode.core.concurrent import (
5-
FutureEx,
6-
check_current_thread_canceled,
7-
run_in_thread,
8-
threaded,
9-
)
4+
from robotcode.core.concurrent import FutureEx, check_current_thread_canceled, run_in_thread
105
from robotcode.core.event import event
116
from robotcode.core.lsp.types import (
127
CodeLens,
@@ -46,8 +41,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None:
4641
if len(self.collect):
4742
capabilities.code_lens_provider = CodeLensOptions(resolve_provider=True if len(self.resolve) > 0 else None)
4843

49-
@rpc_method(name="textDocument/codeLens", param_type=CodeLensParams)
50-
@threaded
44+
@rpc_method(name="textDocument/codeLens", param_type=CodeLensParams, threaded=True)
5145
def _text_document_code_lens(
5246
self, text_document: TextDocumentIdentifier, *args: Any, **kwargs: Any
5347
) -> Optional[List[CodeLens]]:
@@ -74,8 +68,7 @@ def _text_document_code_lens(
7468

7569
return results
7670

77-
@rpc_method(name="codeLens/resolve", param_type=CodeLens)
78-
@threaded
71+
@rpc_method(name="codeLens/resolve", param_type=CodeLens, threaded=True)
7972
def _code_lens_resolve(self, params: CodeLens, *args: Any, **kwargs: Any) -> CodeLens:
8073
results: List[CodeLens] = []
8174

packages/language_server/src/robotcode/language_server/common/parts/commands.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
cast,
1414
)
1515

16-
from robotcode.core.concurrent import threaded
1716
from robotcode.core.lsp.types import (
1817
ErrorCodes,
1918
ExecuteCommandOptions,
@@ -82,8 +81,7 @@ def get_command_name(self, callback: _FUNC_TYPE, name: Optional[str] = None) ->
8281
def extend_capabilities(self, capabilities: ServerCapabilities) -> None:
8382
capabilities.execute_command_provider = ExecuteCommandOptions(list(self.commands.keys()))
8483

85-
@rpc_method(name="workspace/executeCommand", param_type=ExecuteCommandParams)
86-
@threaded
84+
@rpc_method(name="workspace/executeCommand", param_type=ExecuteCommandParams, threaded=True)
8785
def _workspace_execute_command(
8886
self,
8987
command: str,

packages/language_server/src/robotcode/language_server/common/parts/completion.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from itertools import chain
33
from typing import TYPE_CHECKING, Any, Final, List, Optional, Union, cast
44

5-
from robotcode.core.concurrent import check_current_thread_canceled, threaded
5+
from robotcode.core.concurrent import check_current_thread_canceled
66
from robotcode.core.event import event
77
from robotcode.core.lsp.types import (
88
CompletionContext,
@@ -84,8 +84,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None:
8484
completion_item=CompletionOptionsCompletionItemType(label_details_support=True),
8585
)
8686

87-
@rpc_method(name="textDocument/completion", param_type=CompletionParams)
88-
@threaded
87+
@rpc_method(name="textDocument/completion", param_type=CompletionParams, threaded=True)
8988
def _text_document_completion(
9089
self,
9190
text_document: TextDocumentIdentifier,
@@ -159,8 +158,7 @@ def update_completion_item_to_utf16(self, document: TextDocument, item: Completi
159158
item.text_edit.insert = document.range_to_utf16(item.text_edit.insert)
160159
item.text_edit.replace = document.range_to_utf16(item.text_edit.replace)
161160

162-
@rpc_method(name="completionItem/resolve", param_type=CompletionItem)
163-
@threaded
161+
@rpc_method(name="completionItem/resolve", param_type=CompletionItem, threaded=True)
164162
def _completion_item_resolve(self, params: CompletionItem, *args: Any, **kwargs: Any) -> CompletionItem:
165163
results: List[CompletionItem] = []
166164

packages/language_server/src/robotcode/language_server/common/parts/declaration.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from asyncio import CancelledError
22
from typing import TYPE_CHECKING, Any, Final, List, Optional, Union
33

4-
from robotcode.core.concurrent import check_current_thread_canceled, threaded
4+
from robotcode.core.concurrent import check_current_thread_canceled
55
from robotcode.core.event import event
66
from robotcode.core.lsp.types import (
77
DeclarationParams,
@@ -49,8 +49,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None:
4949
if len(self.collect):
5050
capabilities.declaration_provider = True
5151

52-
@rpc_method(name="textDocument/declaration", param_type=DeclarationParams)
53-
@threaded
52+
@rpc_method(name="textDocument/declaration", param_type=DeclarationParams, threaded=True)
5453
def _text_document_declaration(
5554
self,
5655
text_document: TextDocumentIdentifier,

packages/language_server/src/robotcode/language_server/common/parts/definition.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from concurrent.futures import CancelledError
22
from typing import TYPE_CHECKING, Any, Final, List, Optional, Union
33

4-
from robotcode.core.concurrent import check_current_thread_canceled, threaded
4+
from robotcode.core.concurrent import check_current_thread_canceled
55
from robotcode.core.event import event
66
from robotcode.core.lsp.types import (
77
DefinitionParams,
@@ -49,8 +49,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None:
4949
if len(self.collect):
5050
capabilities.definition_provider = True
5151

52-
@rpc_method(name="textDocument/definition", param_type=DefinitionParams)
53-
@threaded
52+
@rpc_method(name="textDocument/definition", param_type=DefinitionParams, threaded=True)
5453
def _text_document_definition(
5554
self,
5655
text_document: TextDocumentIdentifier,

packages/language_server/src/robotcode/language_server/common/parts/diagnostics.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -390,8 +390,7 @@ def publish_diagnostics(self, document: TextDocument, diagnostics: List[Diagnost
390390
def update_document_diagnostics(self, sender: Any, document: TextDocument) -> None:
391391
self.create_document_diagnostics_task(document, True)
392392

393-
@rpc_method(name="textDocument/diagnostic", param_type=DocumentDiagnosticParams)
394-
@threaded
393+
@rpc_method(name="textDocument/diagnostic", param_type=DocumentDiagnosticParams, threaded=True)
395394
def _text_document_diagnostic(
396395
self,
397396
text_document: TextDocumentIdentifier,
@@ -431,8 +430,7 @@ def get_diagnostics_data(self, document: TextDocument) -> DiagnosticsData:
431430

432431
return data
433432

434-
@rpc_method(name="workspace/diagnostic", param_type=WorkspaceDiagnosticParams)
435-
@threaded
433+
@rpc_method(name="workspace/diagnostic", param_type=WorkspaceDiagnosticParams, threaded=True)
436434
def _workspace_diagnostic(
437435
self,
438436
identifier: Optional[str],

packages/language_server/src/robotcode/language_server/common/parts/document_highlight.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from concurrent.futures import CancelledError
22
from typing import TYPE_CHECKING, Any, Final, List, Optional
33

4-
from robotcode.core.concurrent import threaded
4+
from robotcode.core.concurrent import check_current_thread_canceled
55
from robotcode.core.event import event
66
from robotcode.core.lsp.types import (
77
DocumentHighlight,
@@ -37,11 +37,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None:
3737
def collect(sender, document: TextDocument, position: Position) -> Optional[List[DocumentHighlight]]: # NOSONAR
3838
...
3939

40-
@rpc_method(
41-
name="textDocument/documentHighlight",
42-
param_type=DocumentHighlightParams,
43-
)
44-
@threaded
40+
@rpc_method(name="textDocument/documentHighlight", param_type=DocumentHighlightParams, threaded=True)
4541
def _text_document_document_highlight(
4642
self,
4743
text_document: TextDocumentIdentifier,
@@ -61,6 +57,8 @@ def _text_document_document_highlight(
6157
document.position_from_utf16(position),
6258
callback_filter=language_id_filter(document),
6359
):
60+
check_current_thread_canceled()
61+
6462
if isinstance(result, BaseException):
6563
if not isinstance(result, CancelledError):
6664
self._logger.exception(result, exc_info=result)

packages/language_server/src/robotcode/language_server/common/parts/document_symbols.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None:
9797
else:
9898
capabilities.document_symbol_provider = True
9999

100-
@rpc_method(name="textDocument/documentSymbol", param_type=DocumentSymbolParams)
100+
@rpc_method(name="textDocument/documentSymbol", param_type=DocumentSymbolParams, threaded=True)
101101
@threaded
102102
def _text_document_symbol(
103103
self, text_document: TextDocumentIdentifier, *args: Any, **kwargs: Any

0 commit comments

Comments
 (0)