nix-flatpak icon indicating copy to clipboard operation
nix-flatpak copied to clipboard

Undesired behaviour on system bootup

Open nikp123 opened this issue 4 months ago • 7 comments

Hi, sorry if this issue seems nitpicky for such a small thing. But I'd like to point out systemd behavior and Unit relations and how they affect system performance.

As seen here, the unit gets started by wantedBy. This indicates that the target default.target should wait, as it "wants" flatpak-managed-install.service to start/finish first, before it gets treated as completed.

See code: https://github.com/gmodena/nix-flatpak/blob/62f636b87ef6050760a8cb325cadb90674d1e23e/modules/nixos.nix#L12

Now the problem is small, but can add up if the conditions are right. Consider: If an flatpak app needs to be installed/updated, it will hold up boot until that service is finished. This may be undesired behavior because the OS doesn't really depend on flatpak apps being present at login time.

To give a practical example:

Image Here my OS is held up for 2.6 seconds just because that service is checking whether or not any of my flatpak apps need to be updated/installed.

Solution: DOES NOT WORK: ~~Instead of using wantedBy use a pair of bindsTo and partOf. This should fix that behaviour and allow the system to function without waiting for flatpak-managed-install to finish first.~~

nikp123 avatar Aug 21 '25 11:08 nikp123

Hi, sorry if this issue seems nitpicky for such a small thing. But I'd like to point out systemd behavior and Unit relations and how they affect system performance.

Not nitpicky at all, thanks for bringing data!

As seen here, the unit gets started by wantedBy. This indicates that the target default.target should wait, as it "wants" flatpak-managed-install.service to start/finish first, before it gets treated as completed.

This behaviour was implemented to make sure that networking is available before attempting updates / installs. Historically, I found it tricky to have a stable systemd setup across different network managers and distributions. So here I traded boot performance for cross systems consistency.

Consider: If an flatpak app needs to be installed/updated, it will hold up boot until that service is finished.

That's unfortunately expected behaviour. If this is not desired the expectation is that a user would declare update.onActivation=false (the option's default).

Solution: Instead of using wantedBy use a pair of bindsTo and partOf. This should fix that behaviour and allow the system to function without waiting for flatpak-managed-install to finish first.

Thanks for the pointers. Could you help me understand how this would help?

My understanding is that:

  • bindsTo creates a stronger dependency than wantedBy. If the flatpak service fails, wouldn't the target will also stop?
  • partOf makes the service part of the target unit, but doesn't change the timing relationship wrt networking.

Am I missing something?

gmodena avatar Sep 12 '25 20:09 gmodena

bindsTo creates a stronger dependency than wantedBy. If the flatpak service fails, wouldn't the target will also stop? partOf makes the service part of the target unit, but doesn't change the timing relationship wrt networking.

Am I missing something?

Fortunately, not at all, when you visit the documentation. I seem to be the one (kind of) not realizing whats going on here. The behavior it mentions, describes this exactly as you've stated it.

But the weird thing that in practice this works for an another service that I'm maintaining myself, it just disappeared from the boot plot from systemd when i added the bindsTo and partOf. Maybe it's some complicated systemd behaviour, but it no longer holding up targets when i set those two.

I'll try replicating that for this service as well and mention how it goes.

nikp123 avatar Sep 12 '25 21:09 nikp123

Whoops, turns out the service just quite literally never ran when I set those options. This is a mistake on my part.

nikp123 avatar Sep 12 '25 21:09 nikp123

Ok so setting my service as (needs to do common network updates hence the required targets):

[Unit]
After=suspend.target suspend-then-hibernate.target network-online.target
Requires=network-online.target

[Service]
CPUSchedulingPolicy=idle
IOSchedulingClass=idle
Restart=always
RestartSec=60
Type=simple

[Install]
WantedBy=default.target

does not hold up the boot process, it merely just latches onto it as desired.

But flatpak-managed-install with:

[Unit]
After=multi-user.target

[Service]
Restart=on-failure
RestartSec=60s
Type=oneshot

[Install]
WantedBy=default.target

does. For some reason graphical.target does not want to start until its complete.

Image

This requires further investigation

nikp123 avatar Sep 12 '25 21:09 nikp123

Could it be the type of process thats causing the issue here?

nikp123 avatar Sep 12 '25 21:09 nikp123

Image Ok, so the issue at hand is the fact that the service manager launches other services after it ONLY after this one has finished executing.

This of course is desired when building NixOS generations, but kind of undesired in a scenario where you're just booting up.

nikp123 avatar Sep 12 '25 21:09 nikp123

So if we were to go with this route, where we want NixOS rebuilds to be "complete" when all of the flatpak apps were done being set up AND not hold up the system because of it, the only solution it seems to be to split up the services into two seperate targets: one launched by Nix exclusively (oneshot) and one launched by systemd but under a timer or changing its type to exec (letting it run in the background).

nikp123 avatar Sep 12 '25 22:09 nikp123

Yeah I was running into this in a VM I've set up, where boot is stalled out with services.flatpak.enable and I suspect this is because of it waiting for network, etc.

EDIT: looks like this was solved or at least partially addressed in later tags.

krad246 avatar Dec 14 '25 22:12 krad246