narc0tiq / factorio-updater

Factorio update helper for headless servers
MIT License
244 stars 48 forks source link

race condition? #61

Open EphDoering opened 10 months ago

EphDoering commented 10 months ago

On windows when you run Factorio with the updater, it seems to relaunch itself:

   0.348 Factorio initialised
   1.009 Goodbye
Regards from the updater slave
   0.000 2016-11-10 18:43:58; Factorio 0.14.19 (build 25291, win64, alpha)
   0.000 Operating system: Windows 10 (version 1607)

When that happens for me, my subprocess.check_output call returns, while the updater slave continues to try to do it's work. Unfortunately, when the cleanup happens after the main Factorio process exits, it then makes the update unavailable to the updater slave.

I was wondering if you'd experienced this issue yourself?

narc0tiq commented 10 months ago

I can confirm I've never been able to get it to work (at least, not programatically -- you can manually run Factorio in update mode if you tell the updater to leave the files, but you will still face the problem of Factorio auto-starting after each update). It's either something relating to the windowing/rendering system (SDL2/Allegro), or just a specific (intended) behavior that is ellided in the headless version. I suspect (but can't confirm) the same would happen with a graphical Linux build. My theory is that Factorio with a UI has this particular behavior because the player who just launched the update wants to get back to the game -- not to have to launch it again.

Using the updater for non-headless updates is really not an intended use case (graphical Factorio already has a perfectly fine self-updater), so I have no particular ideas to help. I once had the idea that on a completely offline machine one could fake the Factorio website by providing a simple web service with the appropriate JSON endpoints, in which case you would want to also have the binaries handy. But realistically, the updater is only intended to work with headless Factorio.

EphDoering commented 10 months ago

Oh, interesting. Thanks for your insight! I think I got around the GUI launching issue by requesting the download with the isTarget=false parameter from /updater/get-download rather than /get-download-link, but I also downloaded all the updates first, then updated in one command. That allowed for only one UAC prompt. I wonder if the final gui launch control and/or the are-there-more-updates control are easily editable within the update zip.

In any case, I think Factorio has to use the updater slave on windows because on windows you can't overwrite a running executable, so I think it creates a temporary executable updater slave and then executes that to overwrite the main executable. On linux you can rename/ copy over a running executable without any issues so they might not use an update slave on linux at all.

EphDoering commented 10 months ago

Indeed, I just tested out my update script on the Linux GUI version and it doesn't use the update slave so it worked without the race condition issue. It also didn't start up the GUI afterwards, but I guess the command line version with --apply-update should never have to start the GUI back up since when doing an update from the GUI on Linux the GUI never even has to shut down.

Anyway, the checksums of the win64 updates downloaded with isTarget as true and false were identical, so I guess I'm as lost as I was to start.

narc0tiq commented 10 months ago

I think Factorio has to use the updater slave on windows because on windows you can't overwrite a running executable

I think you must be right, that makes perfect sense.

the checksums of the win64 updates downloaded with isTarget as true and false were identical

Wasn't expecting that, what does the parameter even do then? Maybe it's actually just for analytics? I would've expected at least a config file to be different.