Background Updates/Implementation Strategies
Implementation Strategies
Side-by-side approach
This is the approach where Firefox would download an update in the background, apply and install it alongside with the existing installation, and would then wait for the next startup. At startup, the firefox.exe stub would look for the existing installation directories, and would pick the newest one, and start up either by loading xul.dll and the rest of the libraries from that directory or by running a firefox.exe from that directory. After startup, when the next update arrives, the older version (which is not in use any more) will first be removed, then the new update will be applied and it will get picked the next time that Firefox starts up.
Replacement approach
This is the approach where Firefox would download an update in the background, apply and install it in a new directory, and then do one of the two things depending on the OS:
- If the OS supports removing files which are currently in use (*nix), it would just remove the existing installation and move the new directory in place of the old one.
- If the OS doesn't support removing files which are currently in use (Windows), the old directory should be marked to be removed during the next reboot and Firefox should check at startup to see whether the previous directory is in use, and if not it should move the new directory in place of the old directory and then restart.
Challenges
The main challenge in this work is that on Windows, files which are currently in use cannot be replaced. So we cannot really update Firefox as it's running. The side-by-side approach avoids this problem by guaranteeing that files which are in use are never attempted to be overwritten (see below for the only exception to this claim). The replacement approach doesn't avoid this problem completely, so instead it relies on working around the problem duing startup. This may or may not have negative impact on startup performance.
Stub executable
The side-by-side aproach requires a stub executable in order to work correctly. We effectively have this executable, which is the firefox.exe program itself. There is very little code in this file compared to the rest of Firefox living in shared libraries, but we need to have a solution for the case where we need to update this executable (because in the side-by-side approach, the stub does not usually change.)
One approach in updating the stub executable is for it to check inside the library directory that it decides to load libraries from and look for a firefox.exe executable. If one is found there, it indicates that the stub should be updated, so then we can use the current trick of updating update.exe (writing a copy of the stub to another directory, launching that one for the sole purpose of replacing the stub, and then restarting using the new stub). This additional operation only needs to be performed when the stub is actually changed during the update. The updater can check and make sure that the stub is changed when it's applying the update in the background, and remove it (or don't write it to disk in the first place) if it has not changed.