Skip to content

Commit 2eb4cef

Browse files
committed
Use env var to determine number of workers
1 parent efe6ba9 commit 2eb4cef

File tree

1 file changed

+34
-2
lines changed

1 file changed

+34
-2
lines changed

python/lsst/resources/_resourcePath.py

+34-2
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919
import io
2020
import locale
2121
import logging
22+
import multiprocessing
2223
import os
2324
import posixpath
2425
import re
2526
import shutil
2627
import tempfile
2728
import urllib.parse
29+
from functools import cache
2830
from pathlib import Path, PurePath, PurePosixPath
2931
from random import Random
3032

@@ -59,6 +61,36 @@
5961
MAX_WORKERS = 10
6062

6163

64+
@cache
65+
def _get_num_workers() -> int:
66+
f"""Calculate the number of workers to use.
67+
68+
Returns
69+
-------
70+
num : `int`
71+
The number of workers to use. Will use the value of the
72+
``LSST_RESOURCES_NUM_WORKERS`` environment variable if set. Will fall
73+
back to using the CPU count (plus 2) but capped at {MAX_WORKERS}.
74+
"""
75+
num_workers = -1
76+
# CPU_LIMIT is used on nublado.
77+
for env_var in ("LSST_RESOURCES_NUM_WORKERS", "CPU_LIMIT"):
78+
env_value = os.getenv(env_var)
79+
if env_value is not None:
80+
try:
81+
num_workers = int(env_value)
82+
except TypeError:
83+
pass
84+
else:
85+
break
86+
if num_workers == -1:
87+
# Look at the processor count and add 2.
88+
# The processor count will be wrong in pods.
89+
num_workers = multiprocessing.cpu_count() + 2
90+
# But don't ever return more than the maximum allowed.
91+
return min([num_workers, MAX_WORKERS])
92+
93+
6294
class ResourcePath: # numpydoc ignore=PR02
6395
"""Convenience wrapper around URI parsers.
6496
@@ -883,7 +915,7 @@ def _mexists(cls, uris: Iterable[ResourcePath]) -> dict[ResourcePath, bool]:
883915
existence : `dict` of [`ResourcePath`, `bool`]
884916
Mapping of original URI to boolean indicating existence.
885917
"""
886-
exists_executor = concurrent.futures.ThreadPoolExecutor(max_workers=MAX_WORKERS)
918+
exists_executor = concurrent.futures.ThreadPoolExecutor(max_workers=_get_num_workers())
887919
future_exists = {exists_executor.submit(uri.exists): uri for uri in uris}
888920

889921
results: dict[ResourcePath, bool] = {}
@@ -926,7 +958,7 @@ def mtransfer(
926958
A dict of all the transfer attempts with a boolean indicating
927959
whether the transfer succeeded for the target URI.
928960
"""
929-
exists_executor = concurrent.futures.ThreadPoolExecutor(max_workers=MAX_WORKERS)
961+
exists_executor = concurrent.futures.ThreadPoolExecutor(max_workers=_get_num_workers())
930962
future_transfers = {
931963
exists_executor.submit(
932964
to_uri.transfer_from,

0 commit comments

Comments
 (0)