Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove multiprocessing.pool.ThreadPool #498

Merged
merged 5 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 2 additions & 9 deletions docs/source/examples/goto.rst
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
Goto "X" and Find references
========
Goto "X" and Find References
============================

.. example-server:: goto.py
:start-at: import logging







5 changes: 5 additions & 0 deletions docs/source/examples/threaded-handlers.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Threaded Handlers
=================

.. example-server:: threaded_handlers.py
:start-at: import time
7 changes: 7 additions & 0 deletions docs/source/getting-started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,13 @@ These servers are dedicated to demonstrating features of *pygls* itself

:octicon:`code`

.. grid-item-card:: Threaded Handlers
:link: /examples/threaded-handlers
:link-type: doc
:text-align: center

:octicon:`columns`


Tutorial
--------
Expand Down
26 changes: 16 additions & 10 deletions docs/source/howto/migrate-to-v2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ The following methods and functions have been deprecated for some time and have
Renamed ``LanguageServer`` Methods
----------------------------------

The :class:`~pygls.lsp.LanuageServer` class has been moved to the ``pygls.lsp`` module::
The :class:`~pygls.lsp.server.LanuageServer` class has been moved to the ``pygls.lsp`` module::

# Before
from pygls.server import LanguageServer
server = LanguageServer(name="my-language-server", version="v1.0")

# After
from pygls.lsp.server import LanguageServer
from pygls.lsp.server import LanguageServer
server = LanguageServer(name="my-language-server", version="v1.0")

All LSP requests and notifications that can be sent by a server are now automatically generated from the specification, as a result the following methods have been renamed
Expand All @@ -72,15 +72,15 @@ All LSP requests and notifications that can be sent by a server are now automati
``LanguageServer.get_configuration_async`` ``LanguageServer.workspace_configuration_async``
``LanguageServer.publish_diagnostics`` ``LanguageServer.text_document_publish_diagnostics``
``LanguageServer.register_capability`` ``LanguageServer.client_register_capability``
``LanguageServer.register_capability_async`` ``LanguageServer.client_register_capability_async``
``LanguageServer.register_capability_async`` ``LanguageServer.client_register_capability_async``
``LanguageServer.semantic_tokens_refresh`` ``LanguageServer.workspace_semantic_tokens_refresh``
``LanguageServer.semantic_tokens_refresh_async`` ``LanguageServer.workspace_semantic_tokens_refresh_async``
``LanguageServer.show_document`` ``LanguageServer.window_show_document``
``LanguageServer.show_document_async`` ``LanguageServer.window_show_document_async``
``LanguageServer.show_message`` ``LanguageServer.window_show_message``
``LanguageServer.show_message_log`` ``LanguageServer.window_log_message``
``LanguageServer.unregister_capability`` ``LanguageServer.client_unregister_capability``
``LanguageServer.unregister_capability_async`` ``LanguageServer.client_unregister_capability_async``
``LanguageServer.show_document`` ``LanguageServer.window_show_document``
``LanguageServer.show_document_async`` ``LanguageServer.window_show_document_async``
``LanguageServer.show_message`` ``LanguageServer.window_show_message``
``LanguageServer.show_message_log`` ``LanguageServer.window_log_message``
``LanguageServer.unregister_capability`` ``LanguageServer.client_unregister_capability``
``LanguageServer.unregister_capability_async`` ``LanguageServer.client_unregister_capability_async``
================================================== ==============

Additionally all LSP method signatures now require an instance of the corresponding ``params`` object for the method.
Expand Down Expand Up @@ -119,7 +119,7 @@ The helper is now accessed via ``LanguageServer.work_done_progress``
from pygls.server import LanguageServer

server = LanguageServer(name="my-language-server", version="v1.0")

@server.command('progress.example')
async def progress(ls: LanguageServer, *args):
"""Create and start the progress on the client."""
Expand Down Expand Up @@ -394,3 +394,9 @@ If you need to access the underlying protocol object this is now via the ``proto

pygls' base server class has been renamed

Removed ``multiprocessing.pool.ThreadPool``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The :external:py:class:`multiprocessing.pool.ThreadPool` instance has been removed, *pygls* now makes use of :external:py:class:`concurrent.futures.ThreadPoolExecutor` for all threaded tasks.

The ``thread_pool_executor`` attribute of the base ``JsonRPCServer`` class has been removed, the ``ThreadPoolExecutor`` can be accessed via the ``thread_pool`` attribute instead.
5 changes: 1 addition & 4 deletions docs/source/reference/servers.rst
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
Servers
=======

.. autoclass:: pygls.lsp.LanguageServer
.. autoclass:: pygls.lsp.server.LanguageServer
:members:

.. autoclass:: pygls.progress.Progress
:members:

.. autoclass:: pygls.server.JsonRPCServer
:members:



39 changes: 0 additions & 39 deletions examples/servers/json_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
- Defining custom commands
- Progress updates
- Fetching configuration values from the client
- Running methods in a thread
- Async methods
- Dynamic method (un)registration
- Starting a TCP/WebSocket server.
Expand All @@ -33,7 +32,6 @@

import argparse
import asyncio
import time
import uuid
from functools import partial
from typing import Optional
Expand All @@ -42,13 +40,8 @@

from pygls.lsp.server import LanguageServer

COUNT_DOWN_START_IN_SECONDS = 10
COUNT_DOWN_SLEEP_IN_SECONDS = 1


class JsonLanguageServer(LanguageServer):
CMD_COUNT_DOWN_BLOCKING = "countDownBlocking"
CMD_COUNT_DOWN_NON_BLOCKING = "countDownNonBlocking"
CMD_PROGRESS = "progress"
CMD_REGISTER_COMPLETIONS = "registerCompletions"
CMD_SHOW_CONFIGURATION_ASYNC = "showConfigurationAsync"
Expand Down Expand Up @@ -83,38 +76,6 @@ def completions(params: Optional[lsp.CompletionParams] = None) -> lsp.Completion
)


@json_server.command(JsonLanguageServer.CMD_COUNT_DOWN_BLOCKING)
def count_down_10_seconds_blocking(ls: JsonLanguageServer, *args):
"""Starts counting down and showing message synchronously.
It will `block` the main thread, which can be tested by trying to show
completion items.
"""
for i in range(COUNT_DOWN_START_IN_SECONDS):
ls.window_show_message(
lsp.ShowMessageParams(
message=f"Counting down... {COUNT_DOWN_START_IN_SECONDS - i}",
type=lsp.MessageType.Info,
),
)
time.sleep(COUNT_DOWN_SLEEP_IN_SECONDS)


@json_server.command(JsonLanguageServer.CMD_COUNT_DOWN_NON_BLOCKING)
async def count_down_10_seconds_non_blocking(ls: JsonLanguageServer, *args):
"""Starts counting down and showing message asynchronously.
It won't `block` the main thread, which can be tested by trying to show
completion items.
"""
for i in range(COUNT_DOWN_START_IN_SECONDS):
ls.window_show_message(
lsp.ShowMessageParams(
message=f"Counting down... {COUNT_DOWN_START_IN_SECONDS - i}",
type=lsp.MessageType.Info,
),
)
await asyncio.sleep(COUNT_DOWN_SLEEP_IN_SECONDS)


@json_server.command(JsonLanguageServer.CMD_PROGRESS)
async def progress(ls: JsonLanguageServer, *args):
"""Create and start the progress on the client."""
Expand Down
95 changes: 95 additions & 0 deletions examples/servers/threaded_handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
############################################################################
# Copyright(c) Open Law Library. All rights reserved. #
# See ThirdPartyNotices.txt in the project root for additional notices. #
# #
# Licensed under the Apache License, Version 2.0 (the "License") #
# you may not use this file except in compliance with the License. #
# You may obtain a copy of the License at #
# #
# http: // www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
############################################################################
"""This example server demonstrates pygls' ability to run message handlers in a separate
thread.

"""
from __future__ import annotations

import time
import threading

from lsprotocol import types

from pygls.lsp.server import LanguageServer

server = LanguageServer("threaded-server", "v1")


@server.feature(
types.TEXT_DOCUMENT_COMPLETION,
types.CompletionOptions(trigger_characters=["."]),
)
def completions(params: types.CompletionParams | None = None) -> types.CompletionList:
"""Returns completion items."""
return types.CompletionList(
is_incomplete=False,
items=[
types.CompletionItem(label="one"),
types.CompletionItem(label="two"),
types.CompletionItem(label="three"),
types.CompletionItem(label="four"),
types.CompletionItem(label="five"),
],
)


@server.command("count.down.blocking")
def count_down_blocking(ls: LanguageServer, *args):
"""Starts counting down and showing message synchronously.
It will block the main thread, which can be tested by trying to show
completion items.
"""
thread = threading.current_thread()
for i in range(10):
ls.window_show_message(
types.ShowMessageParams(
message=f"Counting down in thread {thread.name!r} ... {10 - i}",
type=types.MessageType.Info,
),
)
time.sleep(1)


@server.thread()
@server.command("count.down.thread")
def count_down_thread(ls: LanguageServer, *args):
"""Starts counting down and showing messages in a separate thread.
It will NOT block the main thread, which can be tested by trying to show
completion items.
"""
thread = threading.current_thread()

for i in range(10):
ls.window_show_message(
types.ShowMessageParams(
message=f"Counting down in thread {thread.name!r} ... {10 - i}",
type=types.MessageType.Info,
),
)
time.sleep(1)


@server.thread()
@server.command("count.down.error")
def count_down_error(ls: LanguageServer, *args):
"""A threaded handler that throws an error."""
1 / 0


if __name__ == "__main__":
server.start_io()
Loading
Loading