Commit Graph

50 Commits

Author SHA1 Message Date
paul chipchase
ae52fd7713 Clean up some of the code documentation regarding virtualization filtering.
#rb trivial
#jira none
#rnx
#preflight 6408843a827cf9251b123cb1

[CL 24558187 by paul chipchase in ue5-main branch]
2023-03-08 08:06:42 -05:00
paul chipchase
b5f5cebd2b Expose more control over when virtualized payloads are placed in cached storage
#rb PJ.Kack
#jira UE-177013
#preflight 63ece283956709374a03eb8a

- The existing config file option 'EnableCacheAfterPull' is now deprecated. If we detect that it is still in the config file we will warn the user about it but continue to apply the value to maintain compatibility.
- Add a new config file option 'EnableCacheOnPull' which controls if a payload is pushed to cached storage after it has been pulled from persistent storage. (Default true)
- Add a new config file option 'EnableCacheOnPush' which controls if a payload is pushed to cached storage before it is pushed to persistent storage. (Default true)
- We now store the info about caching in a single enum bitfield ECachingPolicy.
- Added an up to date comment section about ini file set up for FVirtualizationManager which was previously missing.

[CL 24230636 by paul chipchase in ue5-main branch]
2023-02-15 10:32:09 -05:00
paul chipchase
7e1f558bae Removed the option to opt into virtualization for engine packages. They will be filtered out from virtualization in all cases.
#rb Per.Larsson
#jira UE-177015
#preflight 63eb71ea956709374ab61d5e

- So far nobody has proposed any worthwhile use case for virtualizing engine content given the following downsides:
-- We cannot ever do so internally as we would be unable to distribute the virtualized packages.
-- Projects and the engine packages cannot always be accessed via the same client spec, leading to problems if we try.
-- Engine content is typically small and not suited to virtualization in the first place.
- If we remove the option then we can exclude the engine packages from our VA commandlets which will give less confusing output (at the moment if you try to virtualize a project containing a single package we will report that several thousand packages were found as we need to parse engine content too)
- Deprecated the ini file options, if we detect them we will warn the user that the option is still present and that engine content now will never virtualize.

[CL 24208899 by paul chipchase in ue5-main branch]
2023-02-14 07:19:53 -05:00
mark lintott
8bad2c0365 Removed the callback system from core Analytics system. Fixed up analytics gathering in DerivedDataCache, Virtualization and HttpCacheStore
#rb wes.hunt
#preflight 63be95bd68068a8bd6a4438e

[CL 23651011 by mark lintott in ue5-main branch]
2023-01-11 14:28:01 -05:00
paul chipchase
7c4a834261 Change TryVirtualizePackages/TryRehydratePackages to return the corresponding results structure rather than an enum value.
#rb Per.Larsson
#jira UE-169626
#rnx
#preflight 63bd670a71079a8d1c0e837b

- Since the API was forcing the caller to pass in a results structure to be filled in, we might as well make it the return value.
- Added a ::WasSuccessful method to the results structures that can be used instead of checking if the result had errors or not.
- Remove the reset method from FVirtualizationResult/FRehydrationResult as they no longer need it.
- The older deprecated methods still use the results enum, so we cannot easily deprecate those enums yet.

[CL 23626072 by paul chipchase in ue5-main branch]
2023-01-10 09:15:11 -05:00
paul chipchase
66b32a743f Add a new overload to IVirtualizationSystem::TryRehydratePackages, which takes additional options (via a bitfield enum) and returns more info about the resulting process. The original version has been deprecated.
#rb Per.Larsson
#jira UE-169626
#rnx
#preflight 63bd0ebfd862fdd347bce1fe

### VA System
- This allows us to provide the user with more ways to customize the rehydration and return more detailed info about it if the calling code wishes to log additional info. In both cases we can extend the options and the data returned without changing the API.
- At the moment the only flag we support is 'Checkout', which requests that the rehydration process checkout any package that it needs to modify rather than giving an error. This means that the user does not need to check packages out from revision control before running the rehydration process.
-- We still check if packages can be modified and warn the user if they can't, as package files could be locked in other ways.
- The rehydration process will now long the time taken if verbose logging is set for the category 'LogVirtualization'

### UnrealVirtualizationTool
- The virtualize command now reports how many packages were checked out if the flag was set.
- The rehydration command now supports a '-Checkout' commandline flag, which when enabled will use the new api to checkout the packages that need to be checked out when rehydrated.

[CL 23625132 by paul chipchase in ue5-main branch]
2023-01-10 06:27:20 -05:00
matt peters
71802fb86c Analytics: Backed out 22909100 and 22951911
#rnx

[CL 23583550 by matt peters in ue5-main branch]
2023-01-04 18:51:41 -05:00
paul chipchase
80beaf7cc8 Add a new overload to IVirtualizationSystem::TryVirtualizePackages, which takes additional options (via a bitfield enum) and returns more info about the resulting process. The original version has been drepcated.
#rb Per.Larsson
#jira UE-169626
#rnx
#preflight 639c4112012902cb8db43e13

- This allows us to provide the user with more ways to customize the virtualization and return more detailed info about it if the calling code wishes to log additional info. In both cases we can extend the options and the data returned without changing the API.
- Previously if we virtualized a package that was not checked out in revision control we would warn the user and then skip updating the package file on disk. This means the payloads would be uploaded but the user would be left with no local changes. Since sometimes we know we don't need to check out any package (virtualizing the packages in a change list for example) we don't want to always incur the cost of polling reivision control to see which packages do need checking out. This is why we now allow the caller to request package files be checked out via the new options enum EVirtualizationOptions.
-- If the EVirtualizationOptions::Checkout flag is provided we will poll the revision control status of all package files and then check out those which need it.
-- We still check if packages can be modified and warn the user if they can't, as package files could be locked in other ways.
- Added a new utility function to SourceControlUtilties to make it easier to check out packages. There is similar functionality elsewhere in the code base but the virtualization module is too low level to make use of it.
- Updated existing code that calls ::TryVirtualizePackages and add cases of ''using namespace UE::Virtualization' where required to improve readability.
- The UnrealVirtualizationTool now supports a new cmdline option "-checkout" that can be used when virtualizing packages. This will checkout any package that was actually virtualized so the result can be saved back out to the workspace domain. This means we no longer require the caller to have checked out the packages before running the tool.

[CL 23536832 by paul chipchase in ue5-main branch]
2022-12-16 06:25:07 -05:00
mark lintott
c6f8a9e9d9 Removed AnalyticsEventAttribute.h from the ZenServerInterface and VirtualizationManager header
#rb paul.chipchase
#jira none
#preflight 63625ed70c2e7c8f91891d11

[CL 22911432 by mark lintott in ue5-main branch]
2022-11-02 08:18:25 -04:00
mark lintott
490070be3c Decoupled Zen, DerivedDataCache and Virtualization dependency from Studio Analytics. Systems can now register callbacks to append or modify Event payloads to analytics events by name via the FAnalytics interface.
#rb Nick.Darnell
#fyi Paul.Chipchase,Zousar.Shaker
#preflight 636248d054471d10bedc3749

[CL 22909100 by mark lintott in ue5-main branch]
2022-11-02 06:56:10 -04:00
paul chipchase
462290f718 Extending the VA pulling API to allow for batch pulls
#rb Per.Larsson
#jira UE-163093
#rnx
#preflight 63526abcae33b04ec1ee4a65

- The caller can now request more than one payload to be pulled froim the system at a time. In theory this will allow backends to pull data quicker.
-- The file system backend works with the new system but makes no attempt to take advantage as the backend is not intended for serious production use.
-- The DDC backend should be taking full advantage of the new batching API
-- Note that although the source control API does attempt to take advantage of batching, the internal source control API implementation is not doing so. This will be addressed in a future submit.
- This does make the pulling logic a bit more complicated in FVirtualizationManager as we need to deal with some payloads being found in the first backend, some in the second and some in the third etc.
-- To help deal with this a new class FPullRequestCollection has been added which abstracts a lot of complexity away.

[CL 22707955 by paul chipchase in ue5-main branch]
2022-10-21 22:27:40 -04:00
paul chipchase
8a227b60bb Add a VA rehydration code path that rehydrates a package to a memory buffer rather than replacing the original package on disk.
#rb Per.Larsson
#rnx
#preflight 634805f7f93be0f634b8ed5b

- Added a new FArchive 'FFixedBufferWriterArchive' that will let me serialize to an already allocated, fixed sized memory buffer.
- Moved the code for opening and reading packages to shared utility functions so that it is easier to keep the error messages consistent.
- Moved common code to a new function ::TryRehydrateBuilder so that both rehydration methods can share it.
- Note that technically we are changing the API since now we accept a TConstArrayView for the package file paths for both the virtualization and rehydration paths, but existing code will be compatible with this change.

[CL 22511406 by paul chipchase in ue5-main branch]
2022-10-13 16:28:28 -04:00
paul chipchase
90bea28a6e Setting the cvar 'VA.AllowPkgVirtualization' as part of a device profile will no longer log warnings about the cvar being unregistered.
#rb Per.Larsson
#rnx
#preflight 633ad936c250f60502b2d8cb

- Everything was working but when a cvar is set via a device profile we expect the cvar to be registered sooner, hence the warning.
- Added a new define UE_USE_GLOBAL_CVAR to FVirtualizationManager.cpp, when set we use a static global cvar for 'VA.AllowPkgVirtualization' rather then creating and registering one when the system is mounted.
- Since the cvar can now outlive the manager we also needed to add a way to remove the bound lambda from the cvar when the manager is destroyed.

[CL 22322164 by paul chipchase in ue5-main branch]
2022-10-03 20:36:09 -04:00
paul chipchase
7f9d6e3d01 Added cvar 'VA.AllowPkgVirtualization' which can dynamically enable/disable the virtualization process in the editor without restarting.
#rb Per.Larsson
#jira UE-164278
#rnx
#preflight 63284a248c3def91aa62bd83

- This replaces the old cvar 'VA.DisableVirtualization' which is being removed.
- We will log each time the value is switched to aid in future debugging.
- The name needed to be changed as we needed to invert how it worked, also "DiableVirtualization" was a bit misleading and made people think it turned the entire system off, not just the process of virtualizing packages on submit.
-- The member bEnablePayloadVirtualization was also renamed to bAllowPackageVirtualization to make its purpose clearer.
- The cmdline version was changed from 'VA-DisableVirtualization' to 'VA-SkipPkgVirtualization' for similar reasons.

[CL 22146910 by paul chipchase in ue5-main branch]
2022-09-22 18:02:50 -04:00
paul chipchase
8d77e84166 Refactor the VA pushing API so that we only need to implement a single path
#rb Per.Larsson
#jira UE-163103
#rnx
#preflight 6318989c2b7fe03eb664e9f0

### VirtualizationSystem/VirtualizationManager
- Added an overload of ::Push taking just one FPUshRequest so that people don't have to keep adding MakeArrayView boiler plate when pushing a single request
- Change the order of the last two parameters for the raw ::Push call as this will group all of the payload specific parameters together and leave the target storage type at the end. It is unlikely that anyone is calling the older version but it has been deprecated for safety.

### IVirtualizationBackend
- The none FPushRequest overload of ::PushData is no longer virtual, it just converts the parameters to FPushRequest and calls that overload instead. In this way we now only have one pushing code path in our backends. We could probably look into removing this overload at this point (since the higher level IVirtualizationSystem will now convert all push requests into a FPushRequest form) but it is not considered worth it at the moment when the simple overload covers our needs.
- Removed EPushResult in favour of just returning true/false for the overall operation.If the caller needs a more detailed breakdown then they will have to use an overload that takes an FPushRequest over raw parameters.
-- At the moment FPushRequest does not contain a full breakdown of what happened, so with this submit we are effectively losing the ability to find out if the payload was already in the backends or not, however the batch version of push was already not returning this info so it is not a big loss. Fixing FPushRequest to return a better break down of what happened will be done in UE-160942
- Removed the none batch Push paths from the source control and ddc backends as they already supported batch pushing.
- File backend needed to be converted to supporting batch pushing, which is pretty much the same code as before except we need to iterate over the container of FPushRequests.
-- The backend does not early out on error as it tends to be quite fast. We might want to consider an official policy for the VA system, if we should early out of errors or not.

[CL 21907558 by paul chipchase in ue5-main branch]
2022-09-08 19:35:36 -04:00
paul chipchase
dc4779a5e3 Add a number of ways for the VA backend connections to be changed to lazy initialize on first use.
#rb Devin.Doucette
#jira UE-161599
#rnx
#preflight 6303c8d65a5d4e4624e7bf52

- There are some use cases that require the VA system to be initialized and configured correctly but would prefer that the backend connections only run if absolutely needed (usually when a payload is pulled or pushed for the first time), this change provides four different ways of doing this:
-- Setting [Core.VirtualizationModule]LazyInitConnections=true in the Engine ini file
-- Setting the define 'UE_VIRTUALIZATION_CONNECTION_LAZY_INIT' to 1 in a programs .target.cs
-- Running with the commandline option -VA-LazyInitConnections
-- Setting the cvar 'VA.LazyInitConnections' to 1 (only works if it is set before the VA system is initialized, changing it mid editor via the console does nothing)
--- Note that after the config file, each setting there only opts into lazy initializing the connections, setting the cvar to 0 for example will not prevent the cmdline from opting in etc.

- In the future we will allow the connection code to run async, so the latency can be hidden behind the editor loading, but for the current use case we are taking the minimal approach.
-- This means we only support the backend being in 3 states. No connection has been made yet, the connection is broken and the connection is working.
-- To keep things simple we only record if we have attempted to connect the backends or not. We don't check individual backends nor do we try to reconnect failed ones etc. This is all scheduled for a future work item.
- If the connections are not initialized when the VA system is, we wait until the first time someone calls one of the virtualization methods that will actually use a connection: Push/Pull/Query
-- We try connecting all of the backends at once, even if they won't be used in the call to keep things simple.
- Only the source control backend makes use of the connection system. The horde storage (http) backend could take advantage too, but it is currently unused and most likely going to just be deleted so there seemed little point updating it.
- If we try to run an operation on an unconnected backend we only log to verbose. This is to maintain existing behaviour where a failed backend would not be mounted at all. This logging will likely be revisited in a future work item.

[CL 21511855 by paul chipchase in ue5-main branch]
2022-08-23 13:01:15 -04:00
paul chipchase
8e736177e4 Virtualizing payloads when submitting via the editor will now correctly push the payloads to cache storage backends as well as persistent backends
#rb Per.Larsson
#jira UE-160943, UE-151671
#rnx
#preflight 62fa3334153b17e7462954b3

### Problem
- The virtualization process first checks to see if any of the local payloads are already stored in persistent storage and only try to submit those which aren't, which would mean if we are submitting a package with a local payload that is already in the persistent storage system but not in cached storage we have no way to cache it.
- This logic also introduced problems where filtered out payloads were being virtualized which was fixed with the addition of ENABLE_FILTERING_HACK which was not a robust long term solution.
- Checking if the payloads need to be pushed or not complicated the logic of the virtualization process and makes it harder to understand and make fixes too.

### Fix
- Removed code for ENABLE_FILTERING_HACK and UE_PRECHECK_PAYLOAD_STATUS from the virtualization process
- Removed some code loops from the virtualization process but we still end up with one loop finding all of the package trailers and a second loop setting up the FWorkspaceDomainPayloadProvider
-- This second loop will be removed in a future work item to avoid trying to push duplicate payloads (unless I end up doing that work at the virtualization manager level instead)
- We make one push for cached storage and another for persistent
-- Cached storage push failure will only result in a warning, failing the persistent push will error out as before
-- We need to reset the request states after the cache push. In a future work item we will likely allow a single push to specific both storage solutions, so I am leaving this code using the same set of requests for both pushes.

#robomerge FNMain

[CL 21386503 by paul chipchase in ue5-main branch]
2022-08-15 10:17:46 -04:00
paul chipchase
158dcbe0cc Change the VA graph name LocalStorageHierarchy to 'CacheStorageHierarchy' which better describes it.
#rb Per.Larsson
#jira UE-156189
#rnx
#preflight 62f4c098e60c9215b9bcde08

- The orignal name implied tha the payloads would only be stored locally on the users machine, but the intent is to describe a number of backends that are a) faster than the persistent storage backends b) no guarantee that the payload will be found.
- The new name better describes this functionality.
- We still accept 'LocalStorageHierarchy' but will log a warning informing the user to update their graph but this backwards compatibility code will most likely be removed before 5.1 ships.
-- EStorageType::Local will follow the usual deprecation rules.
- Not strictly related to this change but I also cleaned up and added additional loggng during the initialization of the virtualization manager.

[CL 21333601 by paul chipchase in ue5-main branch]
2022-08-11 05:51:29 -04:00
paul chipchase
085b274017 Renamed the config value [Core.VirtualizationModule].EnablePushToBackend to [Core.VirtualizationModule].EnablePayloadVirtualization so that it makes more sense
#rb trivial
#jira UE-156189
#rnx
#preflight 62f3ab2023003b62a324f67a

- The older versions of this value ([Core.ContentVirtualization].EnablePushToBackend and [Core.VirtualizationModule].EnablePushToBackend) will continue to work but will log a warning to the user telling them to update it.
- It is very unlikely that anyone is actually using these old values and so we can remove this backwards compatibility when 5.1 ships. It is only present to allow us to fix up internal projects and to avoid interrupting people testing the system.

[CL 21317383 by paul chipchase in ue5-main branch]
2022-08-10 09:43:35 -04:00
paul chipchase
07ddbfa4f5 Add a config file option to allow payloads stored in .umap and associated "_builddata.uasset" files to be filtered from the virtualization process. This option defaults to true.
#rb Per.Larsson
#jira UE-156750
#rnx
#preflight 62f212e13b773d04161ee7dd

### Problem
- The payloads stored in map files tend to change more than other assets and would cause a lot more churn in the VA system.
- Some other systems like the landscape component are not able to sensibly continue if their payloads cannot be accessed (heightmaps for exmaple) and would prefer not to allow virtualization.
- As a short term fix we need an option to disable the virtualization on all payloads in map files. Future improvements to the filtering system will allow systems to more easily opt their payloads out of virtualization. When this is functional we might want to change the default from true to false.

### Feature
- The config optionf for this filtering is "[Core.VirtualizationModule]FilterMapContent=True"
- Testing if the owning UObject for a payload is in a umap can get tricky, because we not only need to check the umap but we also need to check if it is in a "_builddata.uasset" file, which is an additional file we store next to a umap containing things like lightmaps etc.
- At the moment we check for this by finding the outermost object for the given owner and check to see if it is a ULevel, UWorld or UMapBuildDataRegistry. This is a bit of a kludge but the types we need to check against are not accessible by this module and making them accessible will pull in a lot of dependencies that we'd prefer not to add.
-- One improvement might be to tag the FLinkerSave with the info we need and passing that into the serialization process rather than trying to work it out ourselves but I am wary of making that change until we are 100% sure that we want to keep this feature.

### Refactor
- Removed IVirtualizationSystem::IsDisabledForObject and replaced it with ::FilterPayload which can return multiple reasons for preventing a payload from virtualizing. (the method was added during 5.1 development so it should be fine to just replace it without deprecation)
-- The original behaviour for FVirtualizationManager::IsDisabledForObject has been moved to FVirtualizationManager::ShouldVirtualizeAsset
- Added a new header to declare enums/types used by the various parts of the virtualization system and started by moving EPayloadFilterReason there from the package trailer header. This allows both the core API and PackageTrailer to use EPayloadFilterReason without creating overburdened header dependencies.
-- EPayloadFilterReason has moved from the UE namespace to UE::Virtualization so the package trailer code needed updating accordingly.
- EditorBulkData will ask the virtualization system for the base filter reason, then add it's own reasons if UE_ENABLE_VIRTUALIZATION_TOGGLE is enabled. This bit of code will be removed for 5.1

[CL 21283179 by paul chipchase in ue5-main branch]
2022-08-09 07:51:55 -04:00
paul chipchase
98ea06b69c Add a config file option to allow projects to customize (or disable) the tag applied to changelist descriptions once the asset virtualization process has run.
#rb none
#rnx
#jira UE-159597
#preflight

- The option is [Core.VirtualizationModule]VirtualizationProcessTag=
- If left blank then no tag will be added
- The internal virtualization process code no longer needs to return a tag since it will now be applied by the virtualization manager instead.
-- Note that we still follow the same logic, we only stamp if no errors were encountered.

[CL 21217286 by paul chipchase in ue5-main branch]
2022-07-22 03:58:27 -04:00
paul chipchase
135e304463 Add an ini file option which when set to true allows package submissions to source control to go ahead even if the virtualization process failed.
#rb none
#jira UE-159596
#rnx
#preflight 62d94160110da0f944afdd32

### Problem
- When rolling our virtualization to projects we have run into a number of set up problems which has caused users to fail to submit packages from the editor as when the virtualization failed we prevented the overall submit from going through.
- Although we will eventually work through all of these problems and add better fault tolerance for now it is annoying for the content team so we need an easy way for a project to allow package submits to be completed even if the virtualization process part of the submit failed.
- Worth noting that the virtualization process failing should never affect the state of the package files, the only downside is that the packages may not be virtualized.

### Fix
- The virtualization/rehydration of packages now return an enum instead of a bool although at the moment we are only returning Success and Failed, but it will allow us to expand in the future
- Combined the code calling the virtualization process from both the source control window and the source control changelist window into a single utility function.
-- Now the two windows only diverge on how they report failure to the user.

- This new utility function now checks to see if the virtualization manager suggests if failing the virtualization process should block any package submission to source control or not.
- I am not happy with this solution, but I haven't come up with anything that feels right, this solution will at least work.

[CL 21199597 by paul chipchase in ue5-main branch]
2022-07-21 08:31:47 -04:00
paul chipchase
24e711dbb6 Make sure that all members in FVirtualizationManager set from the config file have appropriate default values set in case the config file fails to load for some reason.
#rb trivial
#rnx
#preflight 62d92875185da2495f3a8d09

- The missing default values were taken from BaseEngine.ini.
- Made it a bit clearer in the header, which members are set from the config files and which are not.

[CL 21199008 by paul chipchase in ue5-main branch]
2022-07-21 06:38:06 -04:00
paul chipchase
0fd3ca3da4 Add a rehydration command to the stand alone virtualization tool, making it easier to reverse the effects of asset virtualization. Unlike previous processes, this one does not require that we load the package and will just manipulate the data storaged in the package trailer.
#rb Sebastian.Nordgren
#rnx
#jira UE-156436
#preflight 62c287f9a3568e30664eb94f

### VA Standalone Tool
- We now plan to add much more functionality to the tool than just virtualizing and submitting changelists, so to make this easier I am moving the tool towards a design where it should be fairly easy to add new functionality.
- Added FCommand, which is a base class for adding new functionality, simple derive from FCommand and hook it up at the appropriate locations.
-- In the future it should be possible for new command types to automatically register themselves to be initiated from the command line. There should be no need to edit UnrealVirtualizationToolApp to add a new command but this will be done as an additional work item.
-- At the moment FCommand comes with a number of utility methods to call that cover some common source control commands.
-- The original functionality has not yet been moved to the command system and so the code is a little bit weird at the moment. Updating older code to the new system will be done as an additional work item.
- FProject/FPlugin have been moved to their own code files.

### Rehydrate Command
- The rehydrate command will take a number of packages, check them out of source control and then attempt to virtualize them.
- At the moment the chekout logic is fairly basic, we just check out every package supplied, we don't check if the package is virtualized or not yet. This can be improved in additional work items. Ideally by the end of command the only packages that we have checked out should also be rehydrated.
- At the moment the command can either take a path of a specific package, a path of a directory to find packages in, or a changelist containing packages that should be rehydrated.
- A cleint spec (workspace) can optionally be provided, but if not supplied we will attempt to find a client spec for which to check out the packages.
- Currently we will check out the packages to the default change list.

### Rehydrate process
- Added the rehydration process in it's own code files in the virtualization module. Like the virtualization process this is exposed in a public header file and no via the Core interface which means it is very specific to our module/implementation.
- The process expects that the caller will have checked out any required packages from source control. It will treat being unable to update a package file as an error.
- Added PackageUtils.h/.cpp and moved some of the generic code from the virtualization process code there so that it can be shared by the rehydration process.

### Misc
Moving away from the using things like FPackagePath as that requires that the correct mount points have been registered for a project and at the moment (with the flakiness of FConfig*) it seems that the best idea would be to prefer absolute file paths where possible.

[CL 20982284 by paul chipchase in ue5-main branch]
2022-07-07 06:54:33 -04:00
paul chipchase
d5ab533c7f The virtualization system stats are now only printed to the log when the cook commandlet has finished, rather than every time an editor process exits.
#rb Per.Larsson
#rnx
#preflight 62ab3b4a634e82e5d145f5a3

- Dumping of stats to the log file is now something that can be invoked via the IVirtualizationSystem api, so anything can call it, if desired.
- Removed the OnExit callback from the virtualization manager, we no longer print the stats to the log file on exit, but instead print them on demand.
- Add a call at the end of the cooking commandlet to dump the virtualization stats so that they appear around the same part of the log file as the cooking stats.
- Changed the verbosity from 'log' to 'display' so that we can see the stats more easily in horde.

#ROBOMERGE-AUTHOR: paul.chipchase
#ROBOMERGE-SOURCE: CL 20699898 via CL 20699907 via CL 20699911
#ROBOMERGE-BOT: UE5 (Release-Engine-Staging -> Main) (v968-20684695)

[CL 20700183 by paul chipchase in ue5-main branch]
2022-06-17 04:02:32 -04:00