diff --git a/RELEASE.md b/RELEASE.md index 7582004afb..303610b337 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -5,6 +5,12 @@ Please follow the established format: - Use present tense (e.g. 'Add new feature') - Include the ID number for the related PR (or PRs) in parentheses --> +# Upcoming Release + +## Bug fixes and other changes + +- Set Kedro Viz start method to spawn process while launching it from Jupyter Notebook. (#1696) + # Release 7.0.0 ## Major features and improvements diff --git a/package/kedro_viz/api/graphql/router.py b/package/kedro_viz/api/graphql/router.py index 9ab872071b..eb0b257ef7 100644 --- a/package/kedro_viz/api/graphql/router.py +++ b/package/kedro_viz/api/graphql/router.py @@ -1,4 +1,5 @@ """`kedro_viz.api.graphql.router` defines GraphQL routes.""" +# mypy: ignore-errors from fastapi import APIRouter from strawberry.asgi import GraphQL diff --git a/package/kedro_viz/launchers/jupyter.py b/package/kedro_viz/launchers/jupyter.py index c63057249f..407ee7c3c1 100644 --- a/package/kedro_viz/launchers/jupyter.py +++ b/package/kedro_viz/launchers/jupyter.py @@ -107,7 +107,8 @@ def run_viz(port: int = None, local_ns: Dict[str, Any] = None) -> None: else None ) - viz_process = multiprocessing.Process( + process_context = multiprocessing.get_context("spawn") + viz_process = process_context.Process( target=run_server, daemon=True, kwargs={"project_path": project_path, "host": host, "port": port}, diff --git a/package/tests/test_launchers/test_jupyter.py b/package/tests/test_launchers/test_jupyter.py index 9890d13360..6fd116cf31 100644 --- a/package/tests/test_launchers/test_jupyter.py +++ b/package/tests/test_launchers/test_jupyter.py @@ -12,10 +12,17 @@ def patched_check_viz_up(mocker): class TestRunVizLineMagic: def test_run_viz(self, mocker, patched_check_viz_up): - process_init = mocker.patch("multiprocessing.Process") - jupyter_display = mocker.patch("kedro_viz.launchers.jupyter.display") + mock_process_context = mocker.patch("multiprocessing.get_context") + mock_context_instance = mocker.Mock() + + mock_process_context.return_value = mock_context_instance + mock_process = mocker.patch.object(mock_context_instance, "Process") + mock_jupyter_display = mocker.patch("kedro_viz.launchers.jupyter.display") + run_viz() - process_init.assert_called_once_with( + + mock_process_context.assert_called_once_with("spawn") + mock_process.assert_called_once_with( target=run_server, daemon=True, kwargs={ @@ -24,13 +31,15 @@ def test_run_viz(self, mocker, patched_check_viz_up): "port": 4141, }, ) - jupyter_display.assert_called_once() + mock_jupyter_display.assert_called_once() assert set(_VIZ_PROCESSES.keys()) == {4141} # call run_viz another time should reuse the same port - process_init.reset_mock() + mock_process.reset_mock() + run_viz() - process_init.assert_called_once_with( + + mock_process.assert_called_once_with( target=run_server, daemon=True, kwargs={ @@ -58,14 +67,18 @@ def test_exception_when_viz_cannot_be_launched(self, mocker): def test_run_viz_on_databricks(self, mocker, patched_check_viz_up, monkeypatch): monkeypatch.setenv("DATABRICKS_RUNTIME_VERSION", "1") - process_init = mocker.patch("multiprocessing.Process") + mock_process_context = mocker.patch("multiprocessing.get_context") + mock_context_instance = mocker.Mock() + + mock_process_context.return_value = mock_context_instance + mock_process = mocker.patch.object(mock_context_instance, "Process") mocker.patch("kedro_viz.launchers.jupyter._is_databricks", return_value=True) databricks_display = mocker.patch( "kedro_viz.launchers.jupyter._display_databricks_html" ) - process_init.reset_mock() + mock_process.reset_mock() run_viz() - process_init.assert_called_once_with( + mock_process.assert_called_once_with( target=run_server, daemon=True, kwargs={