Add Systemd Socket Activation #11542
Draft
+3
−0
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Changes
What: Support Systemd Socket Activation. Listen on all sockets passed in at startup whenever
SYSTEMD_FDS
is specified.How: When setting up Kestrel, make use of Microsoft.AspNetCore.Hosting.KestrelServerOptionsSystemdExtensions#UseSystemd which seems safe to run anywhere & will only try to listen on passed-in sockets if the appropriate env vars are set.
Why: Having Jellyfin be able to start & stop on demand would lower resource and power consumption for many users when not running Jellyfin. I'm not 100% but I suspect that, for example, having Jellyfin open keeps systemd automounts from operating as desired, keeping drives mounted & keeping them from fully powering down. This consumes significant power and adds noise to my home that I would rather not have. Supporting socket activation would be the easiest way to have Jellyfin start only as needed, for me.
Compatibility: Should work on any ASP.NET Core since 2.0 (August 2017). References:
Links:
For more information on Systemd Socket Activation:
This covers a bunch of other ground, but I was happy to see a solid writeup on Dotnet and Systemd here: https://devblogs.microsoft.com/dotnet/net-core-and-systemd/
Issues
Satisfies https://features.jellyfin.org/posts/2201/systemd-socket-activation-support
Gotchas
I tend-to-think/guess-that if systemd socket activation happens on the port that Jellyfin expects to use, Jellyfin is likely to fail to start (the code above this addition will fail). The theory is that Systemd will have already opened the port, to pass it in, and then Jellyfin will try and fail to open the same port. This gotcha needs validation/testing, but seems likely to me.
My plan is to run systemd socket activation on a separate port than what Jellyfin is configured for, either telling Jellyfin to use a different port & binding on 8096 or just using a different port for socket activation & directing clients to that port (ex: 8095).
Ideally/in-the-future we might also have a way to tell Jellyfin not to try to listen on any TCP/IP ports, using only whatever unix sockets and/or socket activation sockets are available. (This maybe somehow is possible with the current
NetManager
in this file, but I am not well acquainted & have not thoroughly investigated.)Another (weirder) possible option is that both sides (systemd and jellyfin) could try to set
SO_REUSEPORT
on the sockets, so that both can open the same port. It doesn't really matter which of the two sockets sees the incoming connection; the same Jellyfin handlers run on both. This seems like a pretty weird option to juggle to workaround this problem! There's a quirky but academically interesting upside to this route, which is that it could help make non-disruptive in-place Jellyfin upgrades possible by allowing the running two separate instances at once; existing connections could keep being serviced by the old Jellyfin instance while a new upgraded instance could be started. To really be useful, the old instance would need a way to be told to stop listening for connections. There's probably not a ton of user demand for this feature set, but it's some pretty neat system/sockets lore that is pretty neat, and it could well be a very low-code path to working around this gotcha.