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
[BUG] live displays and console printing are not thread safe #1530
Comments
Here's another example showing the same problem happens with regular console printing. import threading
import rich.console
console = rich.console.Console()
def count_to_n(n):
for i in range(n):
console.print(i)
with console.status("testing"):
thread = threading.Thread(target=count_to_n, args=(100,))
thread.start() |
Here's another example showing it affects live displays more generally. import threading
import rich.console
import rich.live
console = rich.console.Console()
def count_to_n(n):
for i in range(n):
console.print(i)
with rich.live.Live("test", console=console, refresh_per_second=20, transient=True):
thread = threading.Thread(target=count_to_n, args=(100,))
thread.start() |
Do you have a recommended workaround to enable in a debug mode? (is there a console-level setting that removes the live refresh behavior or something?) I've been trying to imagine ways to monkey patch this for a workaround, but the thread race being during live display close makes it a bit awkward. Are there any locks in the internal API I can use? |
Hi, I looked at this problem this weekend and found an ok fix. Basically, the console and the live have two separate locks, and they need to share the same lock to have any chance of dealing with the concurrency. So I made them share that lock and also threw a bunch more code under the locks and now it works. I can make a PR for this as well if the maintainer is ok with it. Not sure how to make a test that proves it fixes anything, though. |
Nice @Alex7Li, rich compatibility with concurrency is a major upgrade 👍 |
carrying this patch and the typing bug fixes in a temporary repo I can set as a dependency since I was short-sighted enough to design my app around concurrency before I confirmed if rich supported threading 🤦 https://github.com/GBeauregard/rich-threads/ |
There is a thread safety mechansim in the Console, but it's not entirely based on locks. Each thread has a separate buffer which it writes in to when in the Console context manager. An exclusive lock is only required when writing to the file. Something is clearly going wrong in combination with Live. Sharing the lock with Live and Console would "fix" it, but it's not an optimal solution. @GBeauregard Your examples may be something different. You don't join the threads within the Live context, which means they exit almost immediately. Suspect that's a different issue. It's on my list, I'll take a deep dive on this issue(s) soon. |
@willmcgugan to clarify, this was intentional (to recreate a race condition that occurs during closure of the Live context). This causes stuff to get omitted/broken in the app I wrote almost constantly because of how I wrote it threaded. My current workaround is to just print any important temporary debug messages 4 or 5 times to try to make sure it won't get overwritten 😄 |
Did I solve your problem? Consider sponsoring the ongoing work on Rich and Textual. Or buy me a coffee to say thanks. |
@darrenburns @willmcgugan if it is okay I would like to open a new bug to track this so I can get notifications for it (the bugfix for this was reverted due to problems; this bug is still open) |
There seems to be some sort of threading/race issue with the console and the rich handler (or maybe with live dislays in general?) that causes log lines to get lost or misplaced when used with live displays or status displays.
To Reproduce
Here's a code example that will print out the logs from a queue in a separate thread. Note the log lines aren't then all expected to be above the status, but I was expecting the status to not interfere with it if it's thread safe. In particular the status isn't even getting properly wiped here.
With this a variety of things can happen, the status can get leftover in a line printed at the same time as a log message or sometimes it can even eat a log message entirely.
Here's an example where it ate a line entirely
a lot of the time I get other goofy stuff like this
Platform
Gentoo Linux / kitty 0.23.1
Diagnose
The text was updated successfully, but these errors were encountered: