Skip to content
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] Eww spawns zombie windows and processes #255

Open
3 tasks done
Axarva opened this issue Sep 1, 2021 · 18 comments
Open
3 tasks done

[BUG] Eww spawns zombie windows and processes #255

Axarva opened this issue Sep 1, 2021 · 18 comments
Labels
bug Something isn't working

Comments

@Axarva
Copy link
Contributor

Axarva commented Sep 1, 2021

Checklist before submitting an issue

  • I have searched through the existing closed and open issues for eww and made sure this is not a duplicate
  • I have specifically verified that this bug is not a common user error
  • I am providing as much relevant information as I am able to in this bug report (Minimal config to reproduce the issue for example, if applicable)

Describe the bug

Basically, launching widgets will open your widgets, but sometimes they'll spawn, but refuse to close. Trying eww kill will kill the daemon, but these windows will not be closed. killall eww, however, works.

As far as I can predict, this issue happens after making eww daemon not a dependency for launching eww widgets. I'm not quite sure though.

Reproducing the issue

Use any config and create a widget. Bind the opening of your window to a keybind. Do not launch eww daemon. Press your keybind. Eww will not open windows immediately which is expected.

Now, before eww has finished opening the window, press the keybind again. Try to close this window with the eww close command. It will not work. The only way to remove the window will be killall eww.

This also happens sometimes randomly even when the daemon is running, but I cannot consistently reproduce it.

Expected behaviour

Eww windows to close with the eww close or eww kill commands.

Additional context

Logs:
image

The log says Closing all windows. However, windows aren't closed.

@Axarva Axarva added the bug Something isn't working label Sep 1, 2021
@elkowar
Copy link
Owner

elkowar commented Sep 11, 2021

So what's happening here is that you're sending a close window command before the window has been fully opened? Am I getting that right?

@Axarva
Copy link
Contributor Author

Axarva commented Sep 11, 2021

Nope, an open window command before the windows are fully opened.

@elkowar
Copy link
Owner

elkowar commented Sep 11, 2021

could you share the output of eww debug and eww windows once you encounter an instance of such a zombie window (window that doesn't close)?

@VuiMuich
Copy link

I have experienced this as well, when restarting eww due to a WM reload.
Also sometimes these windows seem to have odd properties and size, not sure if this might be a WM issue.
Will also try to catch some logs and maybe xprops, when I get this next time.

@Axarva
Copy link
Contributor Author

Axarva commented Sep 13, 2021

Here is the output of eww windows:

image

And here's the output of eww debug.

@elkowar
Copy link
Owner

elkowar commented Sep 13, 2021

Interesting, this means that it actually sees the windows as not open, and thus won't close them. I'll investigate

@Animeshz
Copy link
Contributor

In my case it does show the window as open.

I'd guess that since the ipc server runs at the last of server::initialize_server which might have took some time, two instances of the main.rs saw that daemon is not running and started running that function and two ipc_server listeners may attempt to listen one might got disconnected cuz of same file to listen.

@Animeshz
Copy link
Contributor

Animeshz commented Sep 13, 2021

Actually problem even gets increased due to 5 connection retries, this makes the startup of the server very slow as well as chances of this bug to happen. I'd suggest to reduce that to 3 or 2.

I can see there are two ways for solving this:

  1. The wm I use (herbstluftwm) offer a --locked option which prevent it to draw anything on screen until hc unlock is executed in the autostart script (preferably at the end), similar to that if we can lock the socket file somehow at the start of initialize_server or something. Or maybe make a lock file which indicates some instance already have it opened while not started receiving commands (strategy used by vmware etc).
  2. Revoke open command to attempt to start server to open. Make something like mkdir -p for eww daemon which silently start the daemon if does not exist, or do nothing. And force user to do eww -p daemon && eww open <bar> instead (saves from 5 connection attempts, making startup faster).

Edit: Hybrid of two, have two locks a client side a server side, client can't connect till any of client or server lock is present, server cannot attempt to check daemon running or not until server side lock is not released. This will prevent from making breaking change from completely changing default behavior of open command to start the daemon if not running.

@elkowar
Copy link
Owner

elkowar commented Sep 15, 2021

well, option 2 is what we had before - it made usage a lot more confusing, and generally more anoying to deal with when developing, too. Having a better check such as a file based lock would work, however it runs the issue of not getting cleaned up correctly - some people do do pkill eww, which then, well, doesn't necessarily give eww the chance to clean up everything.

If you care about the startup speed, then do start the daemon manually before, just as you showed - there the daemon won't do it's 5 connection attempts, and thus will be a lot faster to start up.

Having some better way of making sure no current server is already running is definitely something worth looking at again - having multiple eww instances running from the same config path is definitely an issue that shouldn't happen

@Animeshz
Copy link
Contributor

Can we just move the init_async_part at the top of server::initialize_server and handle any error to stop the thread handle (instead of ? at end of result)? And reduce connection attempts to 3? Might reduce the chance of this happening to significant extent, but not free from this completely...

Also a regain of lock is something what vmware allows, if a vm is not running & lock is present (I'm not exactly sure how they actually do this).

@VuiMuich
Copy link

VuiMuich commented Sep 15, 2021

On a side note:
Using pkill eww currently is the 'clenaer' experience for me as doing eww kill.
When I use eww kill I regularly end up with one of the three windows I use as my 'bar' being hidden after a WM reload (doing this quite often at the moment as I am working on a few different contributions to leftwm, and checking bug reports).
TBH I am not 100% sure this issue is really eww's fault, or is a regression introduced to leftwm actually. Will do further tests, if I can pin it more down and blame one or the other..
Window eww - tags should be in the center:
2021-09-15-212951_2560x1440_scrot
Killing with pkill and manually reloading leftwm theme:
2021-09-15-213024_2560x1440_scrot
xprops for comparison:
2021-09-15-213042_2560x1440_scrot

Edit2: jsut did a vimdiff on the two xprops outputs, and besides the obvious differences like PID, USER_TIME and SYNC_REQUEST they are identical

@Animeshz
Copy link
Contributor

I had a random thought, can we just apply a lock/mutex for eww [open|open-many|daemon|kill|reload] commands from the start line of main() to the end of main? with a timeout so that subsequent calls to them require to wait until lock is freed or timeout say 5s has been elapsed?

Simple to implement as well as might be free from this unexpected behavior, as the second open command will require to finish old open command if started parallelly 🤔🤔

@Animeshz
Copy link
Contributor

Random thought came to my mind because eww open bar && eww open bar never had this problem i.e. when one waits for the other to finish. Only when launching parallelly this will occur, which we can fix using a virtual lock file.

@VuiMuich
Copy link

Random thought came to my mind because eww open bar && eww open bar never had this problem i.e. when one waits for the other to finish. Only when launching parallelly this will occur, which we can fix using a virtual lock file.

You mean eww daemon && eww open bar? There where also issues, when one tried to open windows before the daemon fully spun up. Therefore I had a script that executed eww open .. until eww window | grep \* returned something.

@Animeshz
Copy link
Contributor

Oh right, it forks the process and returns the parent before complete initialization 🤔🤔. But we can still pass the responsibility to the child fork to unlock the lock for these server-commands, then let the next command to proceed... That will solve the issue if I'm not wrong 👀

@VuiMuich
Copy link

So have a initializing_lock and the child has to wait before returning until the lock is gone as init finished?

@rajoayalew
Copy link

It seems like I have a similar issue based on what has been mentioned in the thread although there hasn't been a new update to this issue since September. Has there been an update to this issue or is there a workaround? Thanks

@tkapias
Copy link

tkapias commented Dec 8, 2022

I may have an issue related to this one too.

  1. I run the daemon at startup.
  2. I have an i3wm key binding to toggle the main windows (eww open bar) or close-all (it check for 'eww state' content to choose).
  • It works fine for a few hours but then there is a glitch and it will open 2 clones, one linked to the daemon process and an independent open process.

  • From that point, the daemon does not respond and I need to kill it to close the window linked to it. But I can use 'eww close bar' to close the other, independant, window.

It's hard to debug this because it can happen 1 or 5h after daemon launch. I don't know what's the trigger. Maybe xscreensaver?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants