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

Conversation

alcarney
Copy link
Collaborator

@alcarney alcarney commented Sep 18, 2024

Description (e.g. "Related to ...", etc.)

This PR makes what should be a small breaking change to simplify the base JsonRPCServer slightly by removing the use of multiprocessing.pool.ThreadPool.

According to the docs, the only difference between the ThreadPool and ThreadPoolExecutor is the API. They even recommend the use of the ThreadPoolExecutor over the ThreadPool as the Future implementation used is compatible with other standard library modules - such as asyncio.

As a result

  • JsonRPCServer.thread_pool now returns a ThreadPoolExecutor
  • JsonRPCServer.thread_pool_executor has been removed
  • Message handling in JsonRPCProtocol has been tweaked to make use of the ThreadPoolExecutor for threaded handlers.

Unless a server actively used the thread_pool or thread_pool_executor attributes they are unlikely to even notice the change. Handlers registered with the @server.thread() decorator should continue to work unmodified.


While I was making changes to JsonRPCProtocol I've also tweaked the logs generated when the server receives an unknown request method - fixes #443

Before

pygls.protocol.json_rpc: error: Failed to handle request 2 textDocument/documentSymbol DocumentSymbolParams(text_document=TextDocumentIdentifier(uri='file://path/to/project/debian/changelog'), work_done_token=None, partial_result_token=None)
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/pygls/protocol/json_rpc.py", line 218, in _get_handler
    return self.fm.builtin_features[feature_name]
           ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
KeyError: 'textDocument/documentSymbol'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/pygls/protocol/json_rpc.py", line 221, in _get_handler
    return self.fm.features[feature_name]
           ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
KeyError: 'textDocument/documentSymbol'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/pygls/protocol/json_rpc.py", line 260, in _handle_request
    handler = self._get_handler(method_name)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/pygls/protocol/json_rpc.py", line 223, in _get_handler
    raise JsonRpcMethodNotFound.of(feature_name)
pygls.exceptions.JsonRpcMethodNotFound: Method Not Found: textDocument/documentSymbol
pygls.protocol.json_rpc: info: Sending data: {"error": {"code": -32601, "message": "Method Not Found: textDocument/documentSymbol"}, "jsonrpc": "2.0", "id": 2}

After

pygls.protocol.json_rpc: warning: Failed to handle request 2, unknown method 'textDocument/documentSymbol'
pygls.protocol.json_rpc: info: Sending data: {"error": {"code": -32601, "message": "Method Not Found: textDocument/documentSymbol"}, "jsonrpc": "2.0", "id": 2}

Code review checklist (for code reviewer to complete)

  • Pull request represents a single change (i.e. not fixing disparate/unrelated things in a single PR)
  • Title summarizes what is changing
  • Commit messages are meaningful (see this for details)
  • Tests have been included and/or updated, as appropriate
  • Docstrings have been included and/or updated, as appropriate
  • Standalone docs have been updated accordingly

Automated linters

You can run the lints that are run on CI locally with:

poetry install --all-extras --with dev
poetry run poe lint

This commit simplifies the base JsonRPCServer slightly by removing the
use of `multiprocessing.pool.ThreadPool`.

According to the docs[1], the only difference between the `ThreadPool`
and `ThreadPoolExecutor` is the API. They even recommend the use of
the `ThreadPoolExecutor` over the `ThreadPool` as the Future used is
compatible with other standard library modules - such as `asyncio`.

As a result
- `JsonRPCServer.thread_pool` now returns a `ThreadPoolExecutor`
- `JsonRPCServer.thread_pool_executor` has been removed
- Message handling in `JsonRPCProtocol` has been tweaked to make use
of the `ThreadPoolExecutor` for threaded handlers.

[1]: https://docs.python.org/3/library/multiprocessing.html#multiprocessing.pool.ThreadPool
@alcarney alcarney requested a review from tombh September 18, 2024 20:02
Copy link
Collaborator

@tombh tombh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As ever a wonderful PR ❤️ Clean code, updated docs, good tests. Thank you.

@alcarney alcarney merged commit f7b6ba5 into openlawlibrary:main Sep 19, 2024
16 checks passed
@alcarney alcarney deleted the remove-thread-pool branch September 19, 2024 19:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Demote traceback to debug logging for unknown method
2 participants