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

Flaky test #859

Open
alcarney opened this issue Jul 21, 2024 · 2 comments
Open

Flaky test #859

alcarney opened this issue Jul 21, 2024 · 2 comments
Labels
bug Something isn't working help wanted Extra attention is needed lsp Issues that relate to the language server os:windows Issues only found on Windows
Milestone

Comments

@alcarney
Copy link
Member

Expected behavior

The test to pass reliably

Actual behavior

The mechanism that should prevent duplicate clients from being spawned fails and leads to errors

Log output

=================================== FAILURES ===================================
_______________ test_get_client_with_many_uris_in_many_projects ________________

server_manager = <function server_manager.<locals>.initialize at 0x7feeedb42160>
demo_workspace = Uri(scheme='file', authority='', path='/home/runner/work/esbonio/esbonio/lib/esbonio/tests/workspaces/demo', query='', fragment='')
docs_workspace = Uri(scheme='file', authority='', path='/home/runner/work/esbonio/esbonio/docs', query='', fragment='')
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_get_client_with_many_uris1')

    @pytest.mark.asyncio
    async def test_get_client_with_many_uris_in_many_projects(
        server_manager: ServerManager,
        demo_workspace: Uri,
        docs_workspace: Uri,
        tmp_path: pathlib.Path,
    ):
        """Ensure that when called in rapid succession, with many uris we only create a
        single client instance for each project."""
    
        server, manager = server_manager(
            dict(
                esbonio=dict(
                    sphinx=dict(pythonCommand=[sys.executable]),
                    buildCommand=["sphinx-build", "-M", "dirhtml", ".", str(tmp_path)],
                ),
            ),
        )  # Ensure that the server is ready
        await server.ready
    
        src_uris = [Uri.for_file(f) for f in pathlib.Path(demo_workspace).glob("**/*.rst")]
        src_uris += [Uri.for_file(f) for f in pathlib.Path(docs_workspace).glob("**/*.rst")]
        coros = [manager.get_client(s) for s in src_uris]
    
        # As with the other cases, this should only "prime" the system
        result = await asyncio.gather(*coros)
        assert all([r is None for r in result])
    
        # There should only have been one client created for each project (in addition to
        # the 'dummy' global scoped client)
        assert len(manager.clients) == 3
    
        demo_client = manager.clients[str(demo_workspace)]
        assert demo_client is not None
        assert demo_client.state is None
    
        docs_client = manager.clients[str(docs_workspace)]
        assert docs_client is not None
        assert docs_client.state is None
    
        # Now if we do the same again we should get the same client instance for each case.
        coros = [manager.get_client(s) for s in src_uris]
        result = await asyncio.gather(*coros)
    
        assert all([(r is demo_client) or (r is docs_client) for r in result])
    
>       assert demo_client.state == ClientState.Running
E       AssertionError: assert <ClientState.Errored: 5> == <ClientState.Running: 3>
E        +  where <ClientState.Errored: 5> = SphinxClient<Errored: Handler <function init_db at 0x7fdaeefac550> for event 'config-inited' threw an exception (exception: table files already exists)>.state
E        +  and   <ClientState.Running: 3> = ClientState.Running

tests/e2e/test_sphinx_manager.py:270: AssertionError
----------------------------- Captured stdout call -----------------------------
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
Running Sphinx v5.3.0
loading intersphinx inventory from https://docs.python.org/3/objects.inv...
loading intersphinx inventory from https://www.sphinx-doc.org/en/master/objects.inv...
loading intersphinx inventory from https://docs.python.org/3/objects.inv...
loading intersphinx inventory from https://www.sphinx-doc.org/en/master/objects.inv...
loading intersphinx inventory from https://docs.python.org/3/objects.inv...
loading intersphinx inventory from https://docs.python.org/3/objects.inv...
loading intersphinx inventory from https://www.sphinx-doc.org/en/master/objects.inv...
loading intersphinx inventory from https://docs.python.org/3/objects.inv...
loading intersphinx inventory from https://www.sphinx-doc.org/en/master/objects.inv...
loading intersphinx inventory from https://docs.python.org/3/objects.inv...
loading intersphinx inventory from https://www.sphinx-doc.org/en/master/objects.inv...
loading intersphinx inventory from https://docs.python.org/3/objects.inv...
loading intersphinx inventory from https://www.sphinx-doc.org/en/master/objects.inv...
loading intersphinx inventory from https://www.sphinx-doc.org/en/master/objects.inv...
myst v1.0.0: MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions=set(), disable_syntax=[], all_links_external=False, url_schemes=('http', 'https', 'mailto', 'ftp'), ref_domains=None, fence_as_directive=set(), number_code_blocks=[], title_to_header=False, heading_anchors=0, heading_slug_func=None, html_meta={}, footnote_transition=True, words_per_minute=200, substitutions={}, linkify_fuzzy_links=True, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, dmath_double_inline=False, update_mathjax=True, mathjax_classes='tex2jax_process|mathjax_process|math|output_area', enable_checkboxes=False, suppress_warnings=[], highlight_code_blocks=True)
myst v1.0.0: MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions=set(), disable_syntax=[], all_links_external=False, url_schemes=('http', 'https', 'mailto', 'ftp'), ref_domains=None, fence_as_directive=set(), number_code_blocks=[], title_to_header=False, heading_anchors=0, heading_slug_func=None, html_meta={}, footnote_transition=True, words_per_minute=200, substitutions={}, linkify_fuzzy_links=True, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, dmath_double_inline=False, update_mathjax=True, mathjax_classes='tex2jax_process|mathjax_process|math|output_area', enable_checkboxes=False, suppress_warnings=[], highlight_code_blocks=True)
myst v1.0.0: MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions=set(), disable_syntax=[], all_links_external=False, url_schemes=('http', 'https', 'mailto', 'ftp'), ref_domains=None, fence_as_directive=set(), number_code_blocks=[], title_to_header=False, heading_anchors=0, heading_slug_func=None, html_meta={}, footnote_transition=True, words_per_minute=200, substitutions={}, linkify_fuzzy_links=True, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, dmath_double_inline=False, update_mathjax=True, mathjax_classes='tex2jax_process|mathjax_process|math|output_area', enable_checkboxes=False, suppress_warnings=[], highlight_code_blocks=True)
myst v1.0.0: MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions=set(), disable_syntax=[], all_links_external=False, url_schemes=('http', 'https', 'mailto', 'ftp'), ref_domains=None, fence_as_directive=set(), number_code_blocks=[], title_to_header=False, heading_anchors=0, heading_slug_func=None, html_meta={}, footnote_transition=True, words_per_minute=200, substitutions={}, linkify_fuzzy_links=True, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, dmath_double_inline=False, update_mathjax=True, mathjax_classes='tex2jax_process|mathjax_process|math|output_area', enable_checkboxes=False, suppress_warnings=[], highlight_code_blocks=True)
myst v1.0.0: MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions=set(), disable_syntax=[], all_links_external=False, url_schemes=('http', 'https', 'mailto', 'ftp'), ref_domains=None, fence_as_directive=set(), number_code_blocks=[], title_to_header=False, heading_anchors=0, heading_slug_func=None, html_meta={}, footnote_transition=True, words_per_minute=200, substitutions={}, linkify_fuzzy_links=True, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, dmath_double_inline=False, update_mathjax=True, mathjax_classes='tex2jax_process|mathjax_process|math|output_area', enable_checkboxes=False, suppress_warnings=[], highlight_code_blocks=True)
myst v1.0.0: MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions=set(), disable_syntax=[], all_links_external=False, url_schemes=('http', 'https', 'mailto', 'ftp'), ref_domains=None, fence_as_directive=set(), number_code_blocks=[], title_to_header=False, heading_anchors=0, heading_slug_func=None, html_meta={}, footnote_transition=True, words_per_minute=200, substitutions={}, linkify_fuzzy_links=True, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, dmath_double_inline=False, update_mathjax=True, mathjax_classes='tex2jax_process|mathjax_process|math|output_area', enable_checkboxes=False, suppress_warnings=[], highlight_code_blocks=True)
myst v1.0.0: MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions=set(), disable_syntax=[], all_links_external=False, url_schemes=('http', 'https', 'mailto', 'ftp'), ref_domains=None, fence_as_directive=set(), number_code_blocks=[], title_to_header=False, heading_anchors=0, heading_slug_func=None, html_meta={}, footnote_transition=True, words_per_minute=200, substitutions={}, linkify_fuzzy_links=True, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, dmath_double_inline=False, update_mathjax=True, mathjax_classes='tex2jax_process|mathjax_process|math|output_area', enable_checkboxes=False, suppress_warnings=[], highlight_code_blocks=True)
----------------------------- Captured stderr call -----------------------------
Content-Length: 634
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"id": 1, "jsonrpc": "2.0", "result": {"capabilities": {"positionEncoding": "utf-16", "textDocumentSync": {"openClose": true, "change": 2, "save": true}, "completionProvider": {"triggerCharacters": [], "resolveProvider": true}, "documentSymbolProvider": true, "workspaceSymbolProvider": {"resolveProvider": false}, "executeCommandProvider": {"commands": []}, "diagnosticProvider": {"interFileDependencies": true, "workspaceDiagnostics": true, "identifier": "esbonio"}, "workspace": {"workspaceFolders": {"supported": true, "changeNotifications": true}, "fileOperations": {}}}, "serverInfo": {"name": "esbonio", "version": "1.0.0b6"}}}Content-Length: 548
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "a933337d-c341-47ac-9d59-c5b1d9e2880e", "scope": "file:///home/runner/work/esbonio/esbonio/lib/esbonio/tests/workspaces/demo", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/lib/esbonio/tests/workspaces/demo", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "a933337d-c341-47ac-9d59-c5b1d9e2880e"}}Content-Length: 548
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "0863af70-e026-4b92-9509-fdd42db44b57", "scope": "file:///home/runner/work/esbonio/esbonio/lib/esbonio/tests/workspaces/demo", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/lib/esbonio/tests/workspaces/demo", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "0863af70-e026-4b92-9509-fdd42db44b57"}}Content-Length: 548
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "0adfe82d-bea5-4f3f-9274-a66ff5e5f24e", "scope": "file:///home/runner/work/esbonio/esbonio/lib/esbonio/tests/workspaces/demo", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/lib/esbonio/tests/workspaces/demo", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "0adfe82d-bea5-4f3f-9274-a66ff5e5f24e"}}Content-Length: 548
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "860d3ca4-8a8b-47f7-9cf3-1ca0f3e6ddd3", "scope": "file:///home/runner/work/esbonio/esbonio/lib/esbonio/tests/workspaces/demo", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/lib/esbonio/tests/workspaces/demo", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "860d3ca4-8a8b-47f7-9cf3-1ca0f3e6ddd3"}}Content-Length: 548
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "af3a849f-fef7-42f3-a469-0debd31739a4", "scope": "file:///home/runner/work/esbonio/esbonio/lib/esbonio/tests/workspaces/demo", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/lib/esbonio/tests/workspaces/demo", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "af3a849f-fef7-42f3-a469-0debd31739a4"}}Content-Length: 548
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "11f20126-86cd-43ae-a492-db2fd19a1e02", "scope": "file:///home/runner/work/esbonio/esbonio/lib/esbonio/tests/workspaces/demo", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/lib/esbonio/tests/workspaces/demo", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "11f20126-86cd-43ae-a492-db2fd19a1e02"}}Content-Length: 548
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "d1496843-e3cd-447a-b50d-649c9b110e51", "scope": "file:///home/runner/work/esbonio/esbonio/lib/esbonio/tests/workspaces/demo", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/lib/esbonio/tests/workspaces/demo", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "d1496843-e3cd-447a-b50d-649c9b110e51"}}Content-Length: 548
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "168c39cc-f6bf-4cf5-a11f-9cd8a9201b36", "scope": "file:///home/runner/work/esbonio/esbonio/lib/esbonio/tests/workspaces/demo", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/lib/esbonio/tests/workspaces/demo", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "670a3c12-0781-43c5-9add-67e08f39c518", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "670a3c12-0781-43c5-9add-67e08f39c518"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "bff467a2-cbec-4fd0-9e1e-b7cc098278fd", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "bff467a2-cbec-4fd0-9e1e-b7cc098278fd"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "a194f185-de28-4a62-b9f0-1c3ff0a73f42", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "a194f185-de28-4a62-b9f0-1c3ff0a73f42"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "50584832-03bf-4b2b-9568-21c584274a59", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "50584832-03bf-4b2b-9568-21c584274a59"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "dbcc271d-46ac-41f0-ac02-7d412f11cf50", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "dbcc271d-46ac-41f0-ac02-7d412f11cf50"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "69e74856-58a0-4b62-8041-99e609fd7a47", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "69e74856-58a0-4b62-8041-99e609fd7a47"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "7da69327-3c93-4b13-81dc-75c40bc50d3d", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "7da69327-3c93-4b13-81dc-75c40bc50d3d"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "b585cead-6ed4-4ccf-9d30-2d935bc68988", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "b585cead-6ed4-4ccf-9d30-2d935bc68988"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "9add26a8-7908-48d8-8462-d7d9b614d96e", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "9add26a8-7908-48d8-8462-d7d9b614d96e"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "320ee0e2-e60b-4431-ac09-b7690b884f1b", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "320ee0e2-e60b-4431-ac09-b7690b884f1b"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "f839719f-26f3-431b-947e-9358a547430c", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "f839719f-26f3-431b-947e-9358a547430c"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "5d155ab8-46bd-43a7-9013-6f54eb0a9d67", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "5d155ab8-46bd-43a7-9013-6f54eb0a9d67"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "8c4c2e79-8332-45dd-8cfe-e8f4063f1aa6", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "8c4c2e79-8332-45dd-8cfe-e8f4063f1aa6"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "e2d1fea9-b401-4354-8998-9e0a6c14d9a6", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "e2d1fea9-b401-4354-8998-9e0a6c14d9a6"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "f85b245e-f82d-414c-83f2-7d295176a97b", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "f85b245e-f82d-414c-83f2-7d295176a97b"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "a526753e-1511-4168-952a-284cc8cc7c47", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "a526753e-1511-4168-952a-284cc8cc7c47"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "dc770229-0676-4ad5-bc67-6890603085f5", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "dc770229-0676-4ad5-bc67-6890603085f5"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "e6680d37-766a-417d-8dac-41371417aa06", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "e6680d37-766a-417d-8dac-41371417aa06"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "f790871d-cf4d-4cfc-809f-ae6671e0ad93", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "f790871d-cf4d-4cfc-809f-ae6671e0ad93"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "99dcb534-329b-4820-9495-fd89f0706f88", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "99dcb534-329b-4820-9495-fd89f0706f88"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "ef71c073-e558-4d68-959e-7e2d277d1814", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "ef71c073-e558-4d68-959e-7e2d277d1814"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "c7fe499f-6903-43aa-86f0-f40443c3826d", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "c7fe499f-6903-43aa-86f0-f40443c3826d"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "5a55f481-e131-49b4-a1c2-cbbe1267e242", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "5a55f481-e131-49b4-a1c2-cbbe1267e242"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "a36aa547-4eaa-42b7-9d98-55012ca1161c", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "a36aa547-4eaa-42b7-9d98-55012ca1161c"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "a40caf29-0efa-49aa-b250-73e14b1782fd", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "a40caf29-0efa-49aa-b250-73e14b1782fd"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "757c6dbb-9b4a-4471-ae07-bb2e071081e9", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "757c6dbb-9b4a-4471-ae07-bb2e071081e9"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "d3203b36-b2bf-4367-9fc8-a1202173f37a", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "d3203b36-b2bf-4367-9fc8-a1202173f37a"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "a9dc7edd-f8cb-4fb5-badd-6aa8cec73d8c", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "a9dc7edd-f8cb-4fb5-badd-6aa8cec73d8c"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "a08bbb41-f35d-49d3-9d90-2b81af96b14d", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "a08bbb41-f35d-49d3-9d90-2b81af96b14d"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "617f48d6-1318-478a-8a29-a4679dcf9fde", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "617f48d6-1318-478a-8a29-a4679dcf9fde"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "64300511-4323-4070-a710-367084b7cfb4", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "64300511-4323-4070-a710-367084b7cfb4"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "6bcff1c2-b872-44c9-9aea-01dcadfd7693", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 112
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientDestroyed", "jsonrpc": "2.0", "params": {"id": "6bcff1c2-b872-44c9-9aea-01dcadfd7693"}}Content-Length: 490
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientCreated", "jsonrpc": "2.0", "params": {"id": "b0b6c542-21b8-45da-8e54-aa606bb16e11", "scope": "file:///home/runner/work/esbonio/esbonio/docs", "config": {"pythonCommand": ["/home/runner/.local/share/hatch/env/virtual/esbonio/KKH4XflV/hatch-test.py3.9-sphinx5/bin/python3"], "buildCommand": ["sphinx-build", "-M", "dirhtml", ".", "./_build"], "cwd": "/home/runner/work/esbonio/esbonio/docs", "pythonPath": ["/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio"]}}}Content-Length: 239
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"params": {"type": 1, "message": "JsonRpcInternalError: Handler <function init_db at 0x7fdaeefac550> for event 'config-inited' threw an exception (exception: table files already exists)"}, "method": "window/showMessage", "jsonrpc": "2.0"}Content-Length: 696
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientErrored", "jsonrpc": "2.0", "params": {"id": "168c39cc-f6bf-4cf5-a11f-9cd8a9201b36", "error": "JsonRpcInternalError: Handler <function init_db at 0x7fdaeefac550> for event 'config-inited' threw an exception (exception: table files already exists)", "detail": "Traceback (most recent call last):\n  File \"/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio/server/features/sphinx_manager/client_subprocess.py\", line 215, in start\n    self.sphinx_info = await self.protocol.send_request_async(\npygls.exceptions.JsonRpcInternalError: Handler <function init_db at 0x7fdaeefac550> for event 'config-inited' threw an exception (exception: table files already exists)\n"}}Content-Length: 207
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"params": {"type": 1, "message": "JsonRpcInternalError: Could not import extension esbonio.relevant_to (exception: No module named 'esbonio.relevant_to')"}, "method": "window/showMessage", "jsonrpc": "2.0"}Content-Length: 632
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"method": "sphinx/clientErrored", "jsonrpc": "2.0", "params": {"id": "b0b6c542-21b8-45da-8e54-aa606bb16e11", "error": "JsonRpcInternalError: Could not import extension esbonio.relevant_to (exception: No module named 'esbonio.relevant_to')", "detail": "Traceback (most recent call last):\n  File \"/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio/server/features/sphinx_manager/client_subprocess.py\", line 215, in start\n    self.sphinx_info = await self.protocol.send_request_async(\npygls.exceptions.JsonRpcInternalError: Could not import extension esbonio.relevant_to (exception: No module named 'esbonio.relevant_to')\n"}}
------------------------------ Captured log call -------------------------------
ERROR    asyncio:base_events.py:1753 Exception in callback EsbonioLanguageServer._finish_task(<Task cancell...nager.py:249>>)
handle: <Handle EsbonioLanguageServer._finish_task(<Task cancell...nager.py:249>>)>
Traceback (most recent call last):
  File "/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio/server/features/sphinx_manager/client_subprocess.py", line 215, in start
    self.sphinx_info = await self.protocol.send_request_async(
asyncio.exceptions.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio/server/features/sphinx_manager/manager.py", line 292, in _create_or_replace_client
    await client
asyncio.exceptions.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/hostedtoolcache/Python/3.9.19/x64/lib/python3.9/asyncio/events.py", line 80, in _run
    self._context.run(self._callback, *self._args)
  File "/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio/server/server.py", line 109, in _finish_task
    if (exc := task.exception()) is not None:
asyncio.exceptions.CancelledError
ERROR    asyncio:base_events.py:1753 Exception in callback EsbonioLanguageServer._finish_task(<Task cancell...nager.py:249>>)
handle: <Handle EsbonioLanguageServer._finish_task(<Task cancell...nager.py:249>>)>
Traceback (most recent call last):
  File "/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio/server/features/sphinx_manager/client_subprocess.py", line 215, in start
    self.sphinx_info = await self.protocol.send_request_async(
asyncio.exceptions.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio/server/features/sphinx_manager/manager.py", line 292, in _create_or_replace_client
    await client
asyncio.exceptions.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/hostedtoolcache/Python/3.9.19/x64/lib/python3.9/asyncio/events.py", line 80, in _run
    self._context.run(self._callback, *self._args)
  File "/home/runner/work/esbonio/esbonio/lib/esbonio/esbonio/server/server.py", line 109, in _finish_task
    if (exc := task.exception()) is not None:
asyncio.exceptions.CancelledError
=========================== short test summary info ============================
FAILED tests/e2e/test_sphinx_manager.py::test_get_client_with_many_uris_in_many_projects - AssertionError: assert <ClientState.Errored: 5> == <ClientState.Running: 3>
 +  where <ClientState.Errored: 5> = SphinxClient<Errored: Handler <function init_db at 0x7fdaeefac550> for event 'config-inited' threw an exception (exception: table files already exists)>.state
 +  and   <ClientState.Running: 3> = ClientState.Running
================== 1 failed, 258 passed, 28 skipped in 45.94s ==================

(Optional) Settings from conf.py

No response

@alcarney alcarney added bug Something isn't working lsp Issues that relate to the language server labels Jul 21, 2024
@alcarney alcarney added this to the 1.0 milestone Jul 21, 2024
alcarney added a commit to alcarney/esbonio that referenced this issue Sep 29, 2024
When `manager.get_client` is called many times in quick
succession (such as on server restart with N files open) this can fool
the `SphinxManager` into creating multiple client instances for a
given configuration scope.

By storing a ``None`` at the relevant scope we allow the SphinxManager
to detect that the scope has already been handled, preventing the
spawning of duplicated client instances.

This should, finally, fix the flaky test issue (swyddfa#859)
@alcarney
Copy link
Member Author

alcarney commented Sep 29, 2024

While this commit appears to have resolved the original cause of flaky-ness, two new sources of flaky-ness appear to have shown themselves...

 ================================== FAILURES ===================================
_______________ test_get_client_with_many_uris_in_many_projects _______________

server_manager = <function server_manager.<locals>.initialize at 0x000002422877AAC0>
demo_workspace = Uri(scheme='file', authority='', path='/D:/a/esbonio/esbonio/lib/esbonio/tests/workspaces/demo', query='', fragment='')
docs_workspace = Uri(scheme='file', authority='', path='/D:/a/esbonio/esbonio/docs', query='', fragment='')
tmp_path = WindowsPath('C:/Users/runneradmin/AppData/Local/Temp/pytest-of-runneradmin/pytest-0/test_get_client_with_many_uris1')

    @pytest.mark.asyncio
    async def test_get_client_with_many_uris_in_many_projects(
        server_manager: ServerManager,
        demo_workspace: Uri,
        docs_workspace: Uri,
        tmp_path: pathlib.Path,
    ):
        """Ensure that when called in rapid succession, with many uris we only create a
        single client instance for each project."""
    
        server, manager = server_manager(
            dict(
                esbonio=dict(
                    sphinx=dict(
                        pythonCommand=[sys.executable],
                        buildCommand=["sphinx-build", "-M", "dirhtml", ".", str(tmp_path)],
                        configOverrides={
                            "html_theme": "alabaster",
                            "html_theme_options": {},
                        },
                    ),
                ),
            ),
        )  # Ensure that the server is ready
        await server.ready
    
        src_uris = [Uri.for_file(f) for f in pathlib.Path(demo_workspace).glob("**/*.rst")]
        src_uris += [Uri.for_file(f) for f in pathlib.Path(docs_workspace).glob("**/*.rst")]
        coros = [manager.get_client(s) for s in src_uris]
    
        # As with the other cases, this should only "prime" the system
        result = await asyncio.gather(*coros)
        assert all([r is None for r in result])
    
        # There should only have been one client created for each project (in addition to
        # the 'dummy' global scoped client)
        assert len(manager.clients) == 3
    
        demo_client = manager.clients[str(demo_workspace)]
        assert demo_client is not None
        assert demo_client.state is None
    
        docs_client = manager.clients[str(docs_workspace)]
        assert docs_client is not None
        assert docs_client.state is None
    
        # Now if we do the same again we should get the same client instance for each case.
        coros = [manager.get_client(s) for s in src_uris]
        result = await asyncio.gather(*coros)
    
        assert all([(r is demo_client) or (r is docs_client) for r in result])
    
>       assert demo_client.state == ClientState.Running
E       assert <ClientState.Errored: 5> == <ClientState.Running: 3>
E        +  where <ClientState.Errored: 5> = SphinxClient<Errored: database is locked>.state
E        +  and   <ClientState.Running: 3> = ClientState.Running

tests\e2e\test_sphinx_manager.py:284: AssertionError
---------------------------- Captured stdout call -----------------------------
Running Sphinx v6.2.1
loading intersphinx inventory from https://ipython.readthedocs.io/en/stable/objects.inv...
loading intersphinx inventory from https://docs.python.org/3/objects.inv...
loading intersphinx inventory from https://www.sphinx-doc.org/en/master/objects.inv...
myst v3.0.1: MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions=set(), disable_syntax=[], all_links_external=False, links_external_new_tab=False, url_schemes=('http', 'https', 'mailto', 'ftp'), ref_domains=None, fence_as_directive=set(), number_code_blocks=[], title_to_header=False, heading_anchors=0, heading_slug_func=None, html_meta={}, footnote_transition=True, words_per_minute=200, substitutions={}, linkify_fuzzy_links=True, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, dmath_double_inline=False, update_mathjax=True, mathjax_classes='tex2jax_process|mathjax_process|math|output_area', enable_checkboxes=False, suppress_warnings=[], highlight_code_blocks=True)

@alcarney
Copy link
Member Author

================================== FAILURES ===================================
_______________ test_get_client_with_many_uris_in_many_projects _______________

server_manager = <function server_manager.<locals>.initialize at 0x0000017E31F1B1A0>
demo_workspace = Uri(scheme='file', authority='', path='/D:/a/esbonio/esbonio/lib/esbonio/tests/workspaces/demo', query='', fragment='')
docs_workspace = Uri(scheme='file', authority='', path='/D:/a/esbonio/esbonio/docs', query='', fragment='')
tmp_path = WindowsPath('C:/Users/runneradmin/AppData/Local/Temp/pytest-of-runneradmin/pytest-2/test_get_client_with_many_uris1')

    @pytest.mark.asyncio
    async def test_get_client_with_many_uris_in_many_projects(
        server_manager: ServerManager,
        demo_workspace: Uri,
        docs_workspace: Uri,
        tmp_path: pathlib.Path,
    ):
        """Ensure that when called in rapid succession, with many uris we only create a
        single client instance for each project."""
    
        server, manager = server_manager(
            dict(
                esbonio=dict(
                    sphinx=dict(
                        pythonCommand=[sys.executable],
                        buildCommand=["sphinx-build", "-M", "dirhtml", ".", str(tmp_path)],
                        configOverrides={
                            "html_theme": "alabaster",
                            "html_theme_options": {},
                        },
                    ),
                ),
            ),
        )  # Ensure that the server is ready
        await server.ready
    
        src_uris = [Uri.for_file(f) for f in pathlib.Path(demo_workspace).glob("**/*.rst")]
        src_uris += [Uri.for_file(f) for f in pathlib.Path(docs_workspace).glob("**/*.rst")]
        coros = [manager.get_client(s) for s in src_uris]
    
        # As with the other cases, this should only "prime" the system
        result = await asyncio.gather(*coros)
        assert all([r is None for r in result])
    
        # There should only have been one client created for each project (in addition to
        # the 'dummy' global scoped client)
        assert len(manager.clients) == 3
    
        demo_client = manager.clients[str(demo_workspace)]
        assert demo_client is not None
        assert demo_client.state is None
    
        docs_client = manager.clients[str(docs_workspace)]
        assert docs_client is not None
        assert docs_client.state is None
    
        # Now if we do the same again we should get the same client instance for each case.
        coros = [manager.get_client(s) for s in src_uris]
        result = await asyncio.gather(*coros)
    
        assert all([(r is demo_client) or (r is docs_client) for r in result])
    
>       assert demo_client.state == ClientState.Running
E       AssertionError: assert <ClientState.Errored: 5> == <ClientState.Running: 3>
E        +  where <ClientState.Errored: 5> = SphinxClient<Errored: [WinError 183] Cannot create a file when that file already exists: 'C:\\Users\\runneradmin\\AppData\\Local\\Temp\\pytest-of-runneradmin\\pytest-2\\test_get_client_with_many_uris1\\dirhtml'>.state
E        +  and   <ClientState.Running: 3> = ClientState.Running

tests\e2e\test_sphinx_manager.py:284: AssertionError
---------------------------- Captured stdout call -----------------------------
Running Sphinx v8.0.2
loading translations [en]... done
loading intersphinx inventory 'ipython' from https://ipython.readthedocs.io/en/stable//objects.inv ...
loading intersphinx inventory 'python' from https://docs.python.org/3//objects.inv ...
loading intersphinx inventory 'sphinx' from https://www.sphinx-doc.org/en/master/objects.inv ...
intersphinx inventory has moved: https://ipython.readthedocs.io/en/stable//objects.inv -> https://ipython.readthedocs.io/en/stable/objects.inv
myst v4.0.0: MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions=set(), disable_syntax=[], all_links_external=False, links_external_new_tab=False, url_schemes=('http', 'https', 'mailto', 'ftp'), ref_domains=None, fence_as_directive=set(), number_code_blocks=[], title_to_header=False, heading_anchors=0, heading_slug_func=None, html_meta={}, footnote_sort=True, footnote_transition=True, words_per_minute=200, substitutions={}, linkify_fuzzy_links=True, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, dmath_double_inline=False, update_mathjax=True, mathjax_classes='tex2jax_process|mathjax_process|math|output_area', enable_checkboxes=False, suppress_warnings=[], highlight_code_blocks=True)

alcarney added a commit that referenced this issue Sep 29, 2024
When `manager.get_client` is called many times in quick
succession (such as on server restart with N files open) this can fool
the `SphinxManager` into creating multiple client instances for a
given configuration scope.

By storing a ``None`` at the relevant scope we allow the SphinxManager
to detect that the scope has already been handled, preventing the
spawning of duplicated client instances.

This should, finally, fix the flaky test issue (#859)
@alcarney alcarney added help wanted Extra attention is needed os:windows Issues only found on Windows labels Oct 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed lsp Issues that relate to the language server os:windows Issues only found on Windows
Projects
Status: Todo
Development

No branches or pull requests

1 participant