From 055adfbac74a2f5038ede1a6780df4d8a64788fb Mon Sep 17 00:00:00 2001 From: Brendan <2bndy5@gmail.com> Date: Fri, 5 Jul 2024 00:39:25 -0700 Subject: [PATCH] add config value to control font fetching max_workers resolves #351 use hard-coded default of 128 max_workers support env var as override --- docs/customization.rst | 13 +++++++++++++ sphinx_immaterial/google_fonts.py | 21 +++++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/docs/customization.rst b/docs/customization.rst index 91f931341..0c7d686cf 100644 --- a/docs/customization.rst +++ b/docs/customization.rst @@ -742,6 +742,19 @@ Configuration Options bundles to the output directory. Source maps are helpful when developing the theme. +.. confval:: sphinx_immaterial_font_fetch_max_workers + + The number of workers executed in parallel when fetching a cache of the specified + :themeconf:`font`. If not specified, this defaults to using 33 maximum *possible* threads. + If set less than or equal to 0, then this will be determined by the + :py:class:`~concurrent.futures.ThreadPoolExecutor` default. + +.. envvar:: SPHINX_IMMATERIAL_FONT_FETCH_MAX_WORKERS + + An environment variable that can be used to override + :confval:`sphinx_immaterial_font_fetch_max_workers`. + This value must be an integer. + .. _version_dropdown: Version Dropdown diff --git a/sphinx_immaterial/google_fonts.py b/sphinx_immaterial/google_fonts.py index 8f355063a..54f13ecda 100644 --- a/sphinx_immaterial/google_fonts.py +++ b/sphinx_immaterial/google_fonts.py @@ -52,7 +52,8 @@ def _adjust_css_urls(css_content: bytes, renamed_fonts: Dict[str, str]) -> str: ) -_MAX_CONCURRENT_FETCHES = 128 +_MAX_CONCURRENT_FETCHES_KEY = "sphinx_immaterial_font_fetch_max_workers" +_MAX_CONCURRENT_FETCHES_ENV_KEY = "SPHINX_IMMATERIAL_FONT_FETCH_MAX_WORKERS" _TTF_FONT_PATHS_KEY = "sphinx_immaterial_ttf_font_paths" @@ -60,11 +61,24 @@ def _adjust_css_urls(css_content: bytes, renamed_fonts: Dict[str, str]) -> str: def add_google_fonts(app: sphinx.application.Sphinx, fonts: List[str]): cache_dir = os.path.join(get_cache_dir(app), "google_fonts") static_dir = os.path.join(app.outdir, "_static") + max_workers: Optional[int] = cast( + int, app.config.config_values.get(_MAX_CONCURRENT_FETCHES_KEY, 128) + ) + if _MAX_CONCURRENT_FETCHES_ENV_KEY in os.environ: + try: + max_workers = int(os.environ.get(_MAX_CONCURRENT_FETCHES_ENV_KEY, "0")) + except ValueError: + logger.warning( + "Environment variable, %s, must be an integer value.", + _MAX_CONCURRENT_FETCHES_ENV_KEY, + ) + if max_workers is not None and max_workers <= 0: + max_workers = None # use default from ThreadPoolExecutor # _static path font_dir = os.path.join(static_dir, "fonts") os.makedirs(font_dir, exist_ok=True) - with concurrent.futures.ThreadPoolExecutor(max_workers=33) as executor: + with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: def to_thread(fn, *args, **kwargs) -> asyncio.Future: return asyncio.wrap_future(executor.submit(fn, *args, **kwargs)) @@ -200,6 +214,9 @@ def _builder_inited(app: sphinx.application.Sphinx): def setup(app: sphinx.application.Sphinx): app.setup_extension("sphinx_immaterial.external_resource_cache") app.connect("builder-inited", _builder_inited) + app.add_config_value( + _MAX_CONCURRENT_FETCHES_KEY, default=128, rebuild="", types=int + ) return { "parallel_read_safe": True,