-
Notifications
You must be signed in to change notification settings - Fork 249
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
Add --replace
option to replace existing services
#746
Comments
It seems that this API uses the Gio/GTK actions (which are fairly poorly documented - best overview I found is here. In essence, any actions defined on a gtk.Application object will be called remotely on a running application if you make a second instance of that gtk application object and call It seems there is actually a Lines 151 to 152 in 198ebe2
This method is missing an argument (leading to So we should fix that quit action, and then we can use it to clear out any running GUI. This won't work if the running GUI is an older version (like 3.0.3), but then you can always just manually quit the GUI. |
I did a bit more digging in the code to figure out how to implement this (and this comment serves to remind myself if not anything else). One thing I really want is to this reliably, meaning free of race conditions (where the code handling What I've found is that dbus keeps a queue of processes that want to claim a specific name, so the replacing processing can put itself in the queue, tell the existing process to quit and then it can be sure that no other process will be started in the meanwhile (there is still the option that there is already another process in the queue that gets the name, but that seems to be enough of a corner case to not care). Because of this ordering, this means that every separate service (GUI/cli, storage service and windows service) has to handle replacing itself (as opposed to hamster cli sending quit messages to all services), because the quit messages and claiming the name has to be coordinated. So, my plan is:
It seems dbus-python does not handle this queuing perfectly (claiming the name does not return whether it was queued or claimed and there is no builtin "wait for claim" feature), but it looks it is possible to query what connection a name is currently assigned to, so I suggest we just poll that a couple of times per second until the name is claimed by us (as an added bonus, we could resend the quit message if the name is claimed by someone else, which I think would give nicer semantics when multiple replacing processes run at the same time, but also lead to more complicated code that has to remember the previous owner, so maybe just keep it simple), or the timeout expires. Polling is not super nice, and there is a way to get NameOwnerChanged (or something like that) events from dbus, but handling those probably requires significantly more complex code (probably needs a mainloop running at a point where there is none yet), so I would suggest just sticking to polling - this is just development code that will not be run often anyway. |
This makes them replace any currently running GUI, storage service or windows service. This is primarily useful during development, to prevent having to kill these services manually. For the two services, this is implemented properly by trying to claim the bus name and if it is taken, calling the quit method on the current instance while the existing claim is kept in the dbus request queue. This ensures that as soon as the name is released, it is claimed again by the new process (preventing a race condition where a service autostart could occur in between). For the GUI, this race condition is not prevented due to the way Gtk/Gio.Application claims its name, but this should be minor enough an issue to not be problematic (especially since the user can always easily quit the GUI manually beforehand). This commit implements most of projecthamster#746.
This replaces the GUI and two background services (by using the recently added `--replace` options). This is helpful during development to easily replace the existing deamons (even when installed system-wide) with a development version, without having to resort to fragile pkill commands. This also updates the README to recommend using this option instead of kill commands. This also removes a note about not calling windows via dbus, since that does not seem to be true with the current codebase. This fixes projecthamster#746
Hamster has two background services (
hamster-service.py
listening onorg.gnome.Hamster
dbus andhamster-windows-service.py
listening onorg.gnome.Hamster.WindowServer
dbus) that handle the database access and window spawning currently. Additionally, the GUI also has aorg.gnome.Hamster.GUI
dbus service that can be used to activate an existing GUI process instead of spawning a new one.During development, you usually want to test a new version of all these services, but by default the existing running services are used. The README documents you can:
But that is cumbersome and prone to maybe killing too much.
I propose we add a
--replace
commandline option (inspiration taken fromgnome-shell --replace
), that will handle this automatically - tell the existing services to quit, and then start new ones.For this, the two background dbus services seem to have a
Quit
method that tells them to stop running, which is convenient and allows very targeted termination.For the GUI, no such method seems to be present, so maybe we need to resort to either figuring out the pid and killing, or just ignoring the service and spawn a new window (and maybe forcibly take over de dbus name if possible).
The README actually documents that the latter is already done:
But this does not seem to work in practice (just ran hamster from flatpak, then ran
./src/hamster-cli.py
which focuses the existing window rather than spawn a new one, and the process returns immediately).The GUI dbus API also seems to be "experimental" still (as documented here), so I'm not sure if its actually used much. In fact, I'm not quite sure what the API really is, I cannot find any dbus setup code and decorators like with the other services. I suspect that the dbus API is implicitly handled by the Gio code and actions defined here, but I'm not sure if that also gives an automatic "quit" action maybe?
The text was updated successfully, but these errors were encountered: