-
Notifications
You must be signed in to change notification settings - Fork 327
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Revert threads usage; "add executor to validate_payload" #676
Conversation
Also note that version is currently 2.0.0-rc.2 - introducing threads between two release candidates does not make sense at all. Such a change would rather mandate a major version increase, like 3.Y.Z. |
Hi @astrand, correct me if I am wrong. |
Hi @astrand, can you explain where the issue arises in using the asyncio documented method for dealing with blocking IO https://docs.python.org/3/library/asyncio-dev.html |
run_in_executor() is in practice just a fancy name for creating threads. However, this library is based on asyncio; not threads. Introducing threads into an application has some serious consequences. For example, it is no longer safe to use os.fork() (or subprocess with preexec_fn). Thus with threads, this library can be incompatible with many existing applications, preventing updates.
7c087b7
to
d8a8ef8
Compare
Python is a language that ideally should support all concurrency mechanisms supported by the platform. In particular, it should support Linux mechanisms such as subprocesses and select-based IO, without using threads. As I mentioned, I think the problem we are trying to solve needs to be better described. open() typically does not block. |
Just because an API is documented, does not mean that there are no issues with it. See https://docs.python.org/3/library/os.html:
Also note that the asyncio example is a CPU bound calculation, not a simple open(). There's a reason for not being able to use normal file descriptions with UNIX/Linux select() - it is typically not necessary since the local file system is considered fast IO. |
Can we get a sample repro, which would help us understand how |
It is the other way around. The use of run_in_executor() prevents using os.fork() and preexec_fn. With this patch to the examples:
You will get: |
Thanks @astrand, an interesting discussion on the issue with using os.fork() by the dev team https://discuss.python.org/t/concerns-regarding-deprecation-of-fork-with-alive-threads/33555/14 |
I see python 3.13 uses spawn as the default start method for multiprocessing, assume because of this issue with fork. |
Thanks for the links. This is a tricky issue, and I don't think upstream Python is paying enough attention to the issue.
In any case, I investigated the issue with the validator. It is not the open() call that takes time, it is this call in messages.py:
On my test CS, the call takes up to 150 ms, with some fairly normal OCPP communication. I guess this could be a problem in some cases. For reference, the default value of loop.slow_callback_duration is 100 ms. With the product I am working on, however, we have a separate process for time critical code, so we prefer that the validation is synchronous. If jsonschema had an API which allowed incremental validation, the problem could be solved by yielding to the event loop during the validation. But apparently it does not. Anyhow, it should be possible to disable the use of threads for the validation; if this feature should be kept. At least two solutions are possible:
We could perhaps even include this in our example code. |
Thanks @astrand, I'd be comfortable with the first solution you've proposed. |
New suggested solution at #678 . |
See discussion at #676 --------- Co-authored-by: Peter Astrand <[email protected]> Co-authored-by: Patrick Roelke <[email protected]>
run_in_executor() is in practice just a fancy name for creating threads. However, this library is based on asyncio; not threads. Introducing threads into an application has some serious consequences. For example, it is no longer safe to use os.fork() (or subprocess with preexec_fn). Thus with threads, this library can be incompatible with many existing applications, preventing updates.