This PR adds a new type of module for integrating into the restore flow. With this interface a module can register itself for restore notifications and be invoked while certain events happen during the restore process.
This refactors a part of the database and adds a new "sync" command that reuses a lot of the backup logic to take a set of sources and apply them to a backend.
Unlike the backup process, the sync copies files verbatim without any encryption.
This PR has a large blast radius because it takes the final step and bumps up the Controller to be fully async.
We have historically done a piece-by-piece update, so all operations were already async but the controller interface was kept synchronous.
With this update, the controller is now fully async and all tests are updated.
Most places where the new C# compiler warns about function names not ending in `Async` were also adressed, giving a massive refactor change.
Functionally, no changes are done.
This PR changes the restore message when no files are restored.
The logic now keeps track of existing files that do not need to be restored, as well as the actual number of bytes written.
The size of restored files was tracked previously, but was instead reporting the size of the written data.
With this update the legacy restore and new restore report the same numbers.
The warning that is shown if no files are restored has been updated to check if existing files were present, and if so, the restore is assumed to have worked as expected, and an information message is logged, instead of the warning message.
This PR adds explicit validation to the size parameters so we ensure that we throw a meaningful error message instead of fail on some later step.
This also fixes an error in an exception message. Should the error scenario ever trigger, it would previously show incorrect data or cause out-of-bounds error instead of the intended error message.
When this object is collected by the garbage collector, the array is returned to the array pool. This moves the responsibility to the garbage collector leading to a more thread-safe approach with less locks, at the cost of potentially using memory for a longer time until the garbage collector picks up the objects.