From 5d8146deeb45ebb59fa8951dce16501dd99ce7cb Mon Sep 17 00:00:00 2001 From: Timur Osmanov <54434686+TOsmanov@users.noreply.github.com> Date: Tue, 23 Sep 2025 17:22:33 +0300 Subject: [PATCH 1/6] disable: multithreaded tag processing --- foliant/preprocessors/utils/preprocessor_ext.py | 1 - 1 file changed, 1 deletion(-) diff --git a/foliant/preprocessors/utils/preprocessor_ext.py b/foliant/preprocessors/utils/preprocessor_ext.py index db2cace..85ec73d 100644 --- a/foliant/preprocessors/utils/preprocessor_ext.py +++ b/foliant/preprocessors/utils/preprocessor_ext.py @@ -159,7 +159,6 @@ def _process_tags_for_all_files(self, ''' self.logger.info(log_msg) - @run_in_thread def process(self, markdown_file_path): self.current_filepath = Path(markdown_file_path) self.current_filename = str(self.current_filepath. From c59f8de06d78f951266115e618a35d8471980133 Mon Sep 17 00:00:00 2001 From: Timur Osmanov <54434686+TOsmanov@users.noreply.github.com> Date: Tue, 23 Sep 2025 17:23:29 +0300 Subject: [PATCH 2/6] Update setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index e83aa31..f89441d 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ description=SHORT_DESCRIPTION, long_description=LONG_DESCRIPTION, long_description_content_type='text/markdown', - version='1.0.5', + version='1.0.6', author='Daniil Minukhin', author_email='ddddsa@gmail.com', url='https://github.com/foliant-docs/foliantcontrib.utils', From 14fb0fe908323c887d9ce08c24cb50da717b07f2 Mon Sep 17 00:00:00 2001 From: Timur Osmanov <54434686+TOsmanov@users.noreply.github.com> Date: Tue, 23 Sep 2025 17:24:20 +0300 Subject: [PATCH 3/6] Update changelog.md --- changelog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/changelog.md b/changelog.md index 903038b..f8a2797 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,7 @@ +# 1.0.6 + +- PreprocessorExt: multithreaded tag processing is disabled. + # 1.0.5 - PreprocessorExt: fixed the definition of `run_in_thread`, which is a decorator for the file processing function. From 4846aa621164be55d802471bc2b5163a9afc0c56 Mon Sep 17 00:00:00 2001 From: Timur Osmanov <54434686+TOsmanov@users.noreply.github.com> Date: Tue, 23 Sep 2025 18:01:41 +0300 Subject: [PATCH 4/6] Update preprocessor_ext.py --- .../preprocessors/utils/preprocessor_ext.py | 39 ++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/foliant/preprocessors/utils/preprocessor_ext.py b/foliant/preprocessors/utils/preprocessor_ext.py index 85ec73d..c3d3654 100644 --- a/foliant/preprocessors/utils/preprocessor_ext.py +++ b/foliant/preprocessors/utils/preprocessor_ext.py @@ -14,19 +14,29 @@ MAX_THREADS = max(1, os.cpu_count() - 2) thread_semaphore = threading.Semaphore(MAX_THREADS) -def run_in_thread(fn): - @wraps(fn) - def run(*args, **kwargs): - def wrapper(): - try: - fn(*args, **kwargs) - finally: - thread_semaphore.release() - - thread_semaphore.acquire() - threading.Thread(target=wrapper, daemon=True).start() +def run_in_thread(enabled=True): + """ + If enabled=False, the function runs normally, without threads. + """ + def actual_decorator(fn): + @wraps(fn) + def wrapper(*args, **kwargs): + if not enabled: + return fn(*args, **kwargs) + + def thread_task(): + try: + fn(*args, **kwargs) + finally: + thread_semaphore.release() + + thread_semaphore.acquire() + thread = threading.Thread(target=thread_task, daemon=True) + thread.start() + return thread - return run + return wrapper + return actual_decorator def allow_fail(msg: str = 'Failed to process tag. Skipping.') -> Callable: """ @@ -159,6 +169,8 @@ def _process_tags_for_all_files(self, ''' self.logger.info(log_msg) + multithread = self.context['config'].get('multithread', False) + @run_in_thread(enabled=multithread) def process(self, markdown_file_path): self.current_filepath = Path(markdown_file_path) self.current_filename = str(self.current_filepath. @@ -192,7 +204,8 @@ def _process_all_files(self, '''Apply function func to all Markdown-files in the working dir''' self.logger.info(log_msg) - @run_in_thread + multithread = self.context['config'].get('multithread', False) + @run_in_thread(enabled=multithread) def process(markdown_file_path): self.current_filepath = Path(markdown_file_path) self.current_filename = str(self.current_filepath. From 830ab34840d787efba1aa1396e0a81d0e013ba08 Mon Sep 17 00:00:00 2001 From: Timur Osmanov <54434686+TOsmanov@users.noreply.github.com> Date: Tue, 23 Sep 2025 18:10:23 +0300 Subject: [PATCH 5/6] Update changelog.md --- changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index f8a2797..2b395f0 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,6 @@ # 1.0.6 -- PreprocessorExt: multithreaded tag processing is disabled. +- PreprocessorExt: add option `multithread` # 1.0.5 From baeb76331f1c1c7a199d93cb7b863d6c91a8d9bc Mon Sep 17 00:00:00 2001 From: Timur Osmanov <54434686+TOsmanov@users.noreply.github.com> Date: Wed, 24 Sep 2025 10:58:41 +0300 Subject: [PATCH 6/6] Update preprocessor_ext.py --- foliant/preprocessors/utils/preprocessor_ext.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/foliant/preprocessors/utils/preprocessor_ext.py b/foliant/preprocessors/utils/preprocessor_ext.py index c3d3654..e9f16d3 100644 --- a/foliant/preprocessors/utils/preprocessor_ext.py +++ b/foliant/preprocessors/utils/preprocessor_ext.py @@ -16,14 +16,14 @@ def run_in_thread(enabled=True): """ - If enabled=False, the function runs normally, without threads. + If enabled=False, returns the original function immediately without wrapping. """ def actual_decorator(fn): + if not enabled: + return fn + @wraps(fn) def wrapper(*args, **kwargs): - if not enabled: - return fn(*args, **kwargs) - def thread_task(): try: fn(*args, **kwargs) @@ -36,6 +36,7 @@ def thread_task(): return thread return wrapper + return actual_decorator def allow_fail(msg: str = 'Failed to process tag. Skipping.') -> Callable: