-
-
Notifications
You must be signed in to change notification settings - Fork 262
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
Asynchronous modules stop processing events on SIGSTOP #253
Comments
Interesting stuff. Do we have an easy way to reproduce this? |
Yeah, it is rather easy to reproduce. First, activate an async module in your i3status.conf: Then, hide your bar, so py3status gets stopped: Trigger the event a few times, i.e., switch window focus a few times (until i3 freezes). |
Hmm, this is a nice problem. So really the modules need to run even when py3ststus is stopped. But modules like Maybe we need to have py3status as a thin layer that just spawns the actual py3status and reads/writes data to/from i3bar etc. Since we can't trap SIGSTOP and have to live. |
Yeah, at least the asynchronous modules should not be stopped. A thin py3status main process, which forks of the actual worker and prints data sounds like a good idea. Another possibility would be to centralize the event processing into another process. But then this process would need to buffer incoming events when the receiving modules are stopped - not sure whether this would be a viable solution. |
Is this due to a recent change in i3, or just a long standing issue that hasn't been noticed before? I think this will need some thinking through to get a nice fix, as ever there are lots of possible options. |
Afaik, this is a long standing issue; the IPC interface was designed to have well-behaving clients. I agree, we should definitely take the time to think about a good solution and also see, how i3 solves it. |
So my thought is
We then use shared memory to communicate. py3 writes
reads
py3status reads
writes
That feels like the most minimal exchange we can get away with, both processes would be checking each other 10 times a second and we'd have some lock contention but it should be fairly minimal. |
Generally, this sounds good. Though, I am not totally sure whether the whole logic of py3status should go into the py3 subprocess. Does it then still make sense to stop the i3status process when we get a SIGSTOP or should it keep on running because the i3status modules do? Also, wouldn't we do the whole processing to generate the i3bar output eventhough it does not get printed because the main process is stopped? |
I think this is the simplest way to start with. a) we would need to know that py3status has stopped. b) some modules trigger other modules to update eg group, so we would have to remember all that. Also the output is only generated when a module has updated so we shouldn't be doing too much work.
I think that might be easier than trying to split things out. The output function |
I was looking at the i3bar protocol http://i3wm.org/docs/i3bar-protocol.html
So maybe we can just use a different signal and not do much more than not output to the bar when it's sent the 'stop' that would be a lot cleaner me thinks. |
A rough cut using SIGUSR2 to stop https://github.com/ultrabug/py3status/compare/master...tobes:i3bar-hidden?expand=1 It needs some polish but the basic theory works from my testing. |
By default i3bar sends a -SIGSTOP to a process sending it data. This causes some modules interacting with i3 ipc to be suspended, which lead to locking issues inside i3. This patch switches to using SIGUSR2 as the suspend signal. The async modules eg window_title_async were affected. see ultrabug#253
@cornerman I've cleaned up my patch a344685 It's much simpler than I initially made it. Could you test if this fixes the issue for you. In my testing It appears to work as intended Really we should look at really 'sleeping' our modules but that can be a thing of the future. |
Good idea, I was not aware of this possibility. But, hmm, this patch crashes py3status whenever the SIGCONT signal is received. Not sure, what is happening. We should definitely be able to SIGSTOP the i3status modules when i3bar is hidden. Also, maybe makes sense to use |
This is true but I want to start with the simplest patch we can.
If you do Do you have any info on the crash? |
Interesting! It works as expected if I run py3status in the console and manually send the signals. But if I run it in i3bar and hide the bar, it dies as soon as the bar is shown again. The logs only say:
|
Ahh, I had this issue before. I think it is a config thing I'll update the patch. |
By default i3bar sends a -SIGSTOP to a process sending it data. This causes some modules interacting with i3 ipc to be suspended, which lead to locking issues inside i3. This patch switches to using SIGUSR2 as the suspend signal. The async modules eg window_title_async were affected. see ultrabug#253
is this any happier |
Sadly, not happier :/ It actually also happens when I launch rofi or when I close i3-nagbar, really not sure what is happening there. Any ideas for debugging? |
Does it work if you run py3status in standalone -s mode? That at least narrows it down to the i3status loop |
There is something because before I had this issue but it went away, I'm not sure if it is a particular module that triggers the issue. |
Yes, this works as expected and does not crash. |
OK, This is a good start. So the problem is in If you just make the
stuff Anyhow we are half way there I think. |
Ah, the error code from i3status is negative, so the check in
|
Weird But we now have a working patch - even if needs more improvements. My view would be to try to get the basic patch into py3status and then add improvements separately. Do you agree or think a different approach is better? Thanks for testing this |
Yes :)
I agree, as of now, we can make i3 crash and therefore this should be fixed asap. Improvements can be done in a later stage. Thanks for fixing this! |
Do you want to make a PR for this? |
You already have it there on your branch and it was your idea to begin with, so I think you should :) |
By default i3bar sends a -SIGSTOP to a process sending it data. This causes some modules interacting with i3 ipc to be suspended, which lead to locking issues inside i3. This patch switches to using SIGUSR2 as the suspend signal. The async modules eg window_title_async were affected. see ultrabug#253
By default i3bar sends a -SIGSTOP to a process sending it data. This causes some modules interacting with i3 ipc to be suspended, which lead to locking issues inside i3. This patch switches to using SIGUSR2 as the suspend signal. The async modules eg window_title_async were affected. see ultrabug#253
Good job guys, and thank you ! |
When i3bar is hidden, the statusline generator gets a SIGSTOP signal. Thus, the asynchronous modules cannot process new events, which currently leads to i3/i3#2280 in i3 - ultimately, this can freeze i3. Depending on how this is solved, it might be desirable to have the event processing in a different process, so it is not stopped. What do you think?
This is also mentioned in #179 for a different use case.
The text was updated successfully, but these errors were encountered: