Update notes on concurrency

This commit is contained in:
James R. Barlow
2023-09-30 17:05:58 -07:00
parent fb006ef39f
commit e9419d2c40
2 changed files with 29 additions and 8 deletions
+24 -8
View File
@@ -39,9 +39,7 @@ Parent process requirements
The :func:`ocrmypdf.ocr` function runs OCRmyPDF similar to command line
execution. To do this, it will:
- create a monitoring thread
- create worker processes (on Linux, forking itself; on Windows and macOS, by
spawning)
- create worker processes or threads
- manage the signal flags of its worker processes
- execute other subprocesses (forking and executing other programs)
@@ -54,7 +52,19 @@ processes.
Creating a child process to call :func:`ocrmypdf.ocr()` is suggested. That
way your application will survive and remain interactive even if
OCRmyPDF fails for any reason.
OCRmyPDF fails for any reason. For example:
.. code-block:: python
from multiprocessing import Process
def ocrmypdf_process():
ocrmypdf.ocr('input.pdf', 'output.pdf')
def call_ocrmypdf_from_my_app():
p = Process(target=ocrmypdf_process)
p.start()
p.join()
Programs that call :func:`ocrmypdf.ocr()` should also install a SIGBUS signal
handler (except on Windows), to raise an exception if access to a memory
@@ -89,12 +99,21 @@ your use case.
Progress monitoring
-------------------
OCRmyPDF uses the ``tqdm`` package to implement its progress bars.
OCRmyPDF uses the ``rich`` package to implement its progress bars.
:func:`ocrmypdf.configure_logging` will set up logging output to
``sys.stderr`` in a way that is compatible with the display of the
progress bar. Use ``ocrmypdf.ocr(...progress_bar=False)`` to disable
the progress bar.
Standard output
---------------
OCRmyPDF is strict about not writing to standard output so that
users can safely use it in a pipeline and produce a valid output
file. A caller application will have to ensure it does not write to
standard output either, if it wants to be compatible with this
behavior and support piping to a file.
Exceptions
----------
@@ -104,9 +123,6 @@ exceptions, some exceptions related to multiprocessing, and
handler. OCRmyPDF will clean up its temporary files and worker processes
automatically when an exception occurs.
Programs that call OCRmyPDF should consider trapping KeyboardInterrupt
so that they allow OCR to terminate with the whole program terminating.
When OCRmyPDF succeeds conditionally, it returns an integer exit code.
Reference
@@ -118,6 +118,11 @@ class StandardExecutor(Executor):
# Regardless of whether we use_threads for worker processes, the log_listener
# must be a thread. Make sure we create the listener after the worker pool,
# so that it does not get forked into the workers.
# If use_threads is False, we are currently guilty of creating a thread before
# forking on Linux, which is not recommended. However, we take a big
# performance hit in pdfinfo if we can't fork. Long term solution is to
# replace most of this with an asyncio implementation, and probably to
# migrate some of pdfinfo into C++ or Rust.
listener = threading.Thread(target=log_listener, args=(log_queue,))
listener.start()