Skip to content

Commit 2dfa20c

Browse files
committed
force multiprocessing start method to be "spawn" at the start of extension,
1 parent 5928d76 commit 2dfa20c

File tree

3 files changed

+15
-20
lines changed

3 files changed

+15
-20
lines changed

jupyter_scheduler/extension.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import asyncio
2+
import multiprocessing
23

34
from jupyter_core.paths import jupyter_data_dir
45
from jupyter_server.extension.application import ExtensionApp
@@ -69,6 +70,15 @@ def _db_url_default(self):
6970
)
7071

7172
def initialize_settings(self):
73+
# Forces new processes to not be forked on Linux.
74+
# This is necessary because `asyncio.get_event_loop()` is bugged in
75+
# forked processes in Python versions below 3.12. This method is
76+
# called by `jupyter_core` by `nbconvert` in the default executor.
77+
78+
# See: https://github.com/python/cpython/issues/66285
79+
# See also: https://github.com/jupyter/jupyter_core/pull/362
80+
multiprocessing.set_start_method("spawn", force=True)
81+
7282
super().initialize_settings()
7383

7484
create_tables(self.db_url, self.drop_tables)

jupyter_scheduler/job_files_manager.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
from multiprocessing import Process
12
import os
23
import random
34
import tarfile
4-
import multiprocessing as mp
5+
56
from typing import Dict, List, Optional, Type
67

78
import fsspec
@@ -23,15 +24,7 @@ async def copy_from_staging(self, job_id: str, redownload: Optional[bool] = Fals
2324
output_filenames = self.scheduler.get_job_filenames(job)
2425
output_dir = self.scheduler.get_local_output_path(model=job, root_dir_relative=True)
2526

26-
# The MP context forces new processes to not be forked on Linux.
27-
# This is necessary because `asyncio.get_event_loop()` is bugged in
28-
# forked processes in Python versions below 3.12. This method is
29-
# called by `jupyter_core` by `nbconvert` in the default executor.
30-
#
31-
# See: https://github.com/python/cpython/issues/66285
32-
# See also: https://github.com/jupyter/jupyter_core/pull/362
33-
mp_ctx = mp.get_context("spawn")
34-
p = mp_ctx.Process(
27+
p = Process(
3528
target=Downloader(
3629
output_formats=job.output_formats,
3730
output_filenames=output_filenames,

jupyter_scheduler/scheduler.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import multiprocessing as mp
1+
from multiprocessing import Process
22
import os
33
import random
44
import shutil
@@ -481,15 +481,7 @@ def create_job(self, model: CreateJob) -> str:
481481
else:
482482
self.copy_input_file(model.input_uri, staging_paths["input"])
483483

484-
# The MP context forces new processes to not be forked on Linux.
485-
# This is necessary because `asyncio.get_event_loop()` is bugged in
486-
# forked processes in Python versions below 3.12. This method is
487-
# called by `jupyter_core` by `nbconvert` in the default executor.
488-
#
489-
# See: https://github.com/python/cpython/issues/66285
490-
# See also: https://github.com/jupyter/jupyter_core/pull/362
491-
mp_ctx = mp.get_context("spawn")
492-
p = mp_ctx.Process(
484+
p = Process(
493485
target=self.execution_manager_class(
494486
job_id=job.job_id,
495487
staging_paths=staging_paths,

0 commit comments

Comments
 (0)