Files
UnrealEngineUWP/Engine/Source/Developer/Virtualization/Private/VirtualizationManager.cpp

1415 lines
48 KiB
C++
Raw Normal View History

// Copyright Epic Games, Inc. All Rights Reserved.
#include "VirtualizationManager.h"
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
#include "HAL/PlatformTime.h"
#include "IVirtualizationBackend.h"
#include "Logging/MessageLog.h"
#include "Misc/CommandLine.h"
#include "Misc/ConfigCacheIni.h"
#include "Misc/CoreDelegates.h"
#include "Misc/PackageName.h"
#include "Misc/PackagePath.h"
#include "Misc/Parse.h"
#include "Misc/Paths.h"
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
#include "Misc/ScopeLock.h"
#include "PackageSubmissionChecks.h"
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
#include "ProfilingDebugging/CookStats.h"
#include "VirtualizationFilterSettings.h"
#define LOCTEXT_NAMESPACE "Virtualization"
namespace UE::Virtualization
{
UE_REGISTER_VIRTUALIZATION_SYSTEM(UE::Virtualization::FVirtualizationManager, Default);
/** Utility struct, similar to FScopeLock but allows the lock to be enabled/disabled more easily */
struct FConditionalScopeLock
{
UE_NONCOPYABLE(FConditionalScopeLock);
FConditionalScopeLock(FCriticalSection* InSyncObject, bool bShouldLock)
{
checkf(InSyncObject != nullptr, TEXT("InSyncObject must point to a valid FCriticalSection"));
if (bShouldLock)
{
SyncObject = InSyncObject;
SyncObject->Lock();
}
else
{
SyncObject = nullptr;
}
}
/** Destructor that performs a release on the synchronization object. */
~FConditionalScopeLock()
{
if (SyncObject != nullptr)
{
SyncObject->Unlock();
}
}
private:
FCriticalSection* SyncObject;
};
Allow the virtualization of assets to be opt in, as well as opt out. This would allow a project to selectively turn on virtualization for specific locations or plugins rather than for the whole project by default. #rb PJ.Kack #jira UE-133473 #preflight 620bf6ae483ff0ae5ec22257 ### VirtualizationManager - Added EPackageFilterMode that can be set via [Core.ContentVirtualization] in the config file to control the default virtualization behavior. -- When set to EPackageFilterMode::OptOut(the default) all package paths will virtualize unless excluded by a pattern in UVirtualizationFilterSettings::ExcludePackagePaths. -- When set to EPackageFilterMode::OptIn then no package path will virtualize unless included by a pattern in UVirtualizationFilterSettings::IncludePackagePaths. - Added a TRACE_CPUPROFILER_EVENT_SCOPE to the constructor and ::MountBackends to better track the set up time costs. - Change use of FConfigCacheIni::LoadLocalIniFile to use GConfig, there is no need to load our own. - Improved verbose logging to show when a payload is rejected via filtering. - We now early out if all payloads being requested in a push are rejected during validation. - Renamed the FString overload for ::ShouldVirtualizePackage to ::ShouldVirtualize to make the difference clearer. - Added support for UVirtualizationFilterSettings::ExcludePackagePaths when filtering ### UVirtualizationFilterSettings - Now has a new FString array ExcludePackagePaths, which contains the paths/patterns used to force packages to be virtualized when filtering. [CL 19010992 by paul chipchase in ue5-main branch]
2022-02-16 01:27:09 -05:00
bool LexTryParseString(EPackageFilterMode& OutValue, FStringView Buffer)
{
if (Buffer == TEXT("OptOut"))
{
OutValue = EPackageFilterMode::OptOut;
return true;
}
else if (Buffer == TEXT("OptIn"))
{
OutValue = EPackageFilterMode::OptIn;
return true;
}
return false;
}
/* Utility function for building up a lookup table of all available IBackendFactory interfaces*/
FVirtualizationManager::FRegistedFactories FindBackendFactories()
{
FVirtualizationManager::FRegistedFactories BackendFactories;
TArray<IVirtualizationBackendFactory*> FactoriesArray = IModularFeatures::Get().GetModularFeatureImplementations<IVirtualizationBackendFactory>(FName("VirtualizationBackendFactory"));
for (IVirtualizationBackendFactory* FactoryInterface : FactoriesArray)
{
checkf(FactoryInterface != nullptr, TEXT("A nullptr was added to the modular features for 'VirtualizationBackendFactory'"));
const FName FactoryName = FactoryInterface->GetName();
if (!BackendFactories.Contains(FactoryName))
{
BackendFactories.Add(FactoryName, FactoryInterface);
}
else
{
UE_LOG(LogVirtualization, Error, TEXT("Duplicate IBackendFactory found! Name '%s'"), *FactoryName.ToString());
}
}
return BackendFactories;
}
/* Utility function for finding entries in a given string*/
TArray<FString> ParseEntries(const FString& Data)
{
TArray<FString> Entries;
const TCHAR* DataPtr = *Data;
const TCHAR* EntryLabel = TEXT("Entry=");
const int32 EntryLabelLength = FCString::Strlen(EntryLabel);
FString ConfigEntryName;
while (FParse::Value(DataPtr, EntryLabel, ConfigEntryName))
{
Entries.Add(ConfigEntryName);
// Skip head so we can look for any additional entries (note that we might not skip past the existing
// entry has we have no idea how much whitespace was ignored by FParse, but it will be enough)
DataPtr += EntryLabelLength + ConfigEntryName.Len();
}
return Entries;
}
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
/**
* Profiling data allowing us to track how payloads are being push/pulled during the lifespan of the process. Note that as all backends are
* created at the same time, we don't need to add locked when accessing the maps. In addition FCookStats is thread safe when adding hits/misses
* so we don't have to worry about that either.
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
* We keep the FCookStats here rather than as a member of IVirtualizationBackend to try and avoid the backends needing to be aware of the data that
* we are gathering at all. This way all profiling code is kept to this cpp.
*/
namespace Profiling
{
#if ENABLE_COOK_STATS
TMap<FString, FCookStats::CallStats> CacheStats;
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
TMap<FString, FCookStats::CallStats> PushStats;
TMap<FString, FCookStats::CallStats> PullStats;
void CreateStats(const IVirtualizationBackend& Backend)
{
CacheStats.Add(Backend.GetDebugName());
PushStats.Add(Backend.GetDebugName());
PullStats.Add(Backend.GetDebugName());
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
}
FCookStats::CallStats& GetCacheStats(const IVirtualizationBackend& Backend)
{
return *CacheStats.Find(Backend.GetDebugName());
}
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
FCookStats::CallStats& GetPushStats(const IVirtualizationBackend& Backend)
{
return *PushStats.Find(Backend.GetDebugName());
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
}
FCookStats::CallStats& GetPullStats(const IVirtualizationBackend& Backend)
{
return *PullStats.Find(Backend.GetDebugName());
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
}
/** Returns true if we have gathered any profiling data at all */
bool HasProfilingData()
{
auto HasAccumulatedData = [](const TMap<FString, FCookStats::CallStats>& Stats)->bool
{
for (const auto& Iterator : Stats)
{
if (Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Counter) > 0)
{
return true;
}
if (Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Miss, FCookStats::CallStats::EStatType::Counter) > 0)
{
return true;
}
}
return false;
};
return HasAccumulatedData(CacheStats) || HasAccumulatedData(PushStats) || HasAccumulatedData(PullStats);
}
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
void LogStats()
{
if (!HasProfilingData())
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
{
return; // Early out if we have no data
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
}
UE_LOG(LogVirtualization, Log, TEXT(""));
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
UE_LOG(LogVirtualization, Log, TEXT("Virtualization ProfileData"));
UE_LOG(LogVirtualization, Log, TEXT("======================================================================================="));
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
if (CacheStats.Num() > 0)
{
UE_LOG(LogVirtualization, Log, TEXT("%-40s|%17s|%12s|%14s|"), TEXT("Caching Data"), TEXT("TotalSize (MB)"), TEXT("TotalTime(s)"), TEXT("DataRate(MB/S)"));
UE_LOG(LogVirtualization, Log, TEXT("----------------------------------------|-----------------|------------|--------------|"));
for (const auto& Iterator : CacheStats)
{
const double Time = Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Cycles) * FPlatformTime::GetSecondsPerCycle();
const int64 DataSizeMB = Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Bytes) / (1024 * 1024);
const double MBps = Time != 0.0 ? (DataSizeMB / Time) : 0.0;
UE_LOG(LogVirtualization, Log, TEXT("%-40.40s|%17" UINT64_FMT "|%12.3f|%14.3f|"),
*Iterator.Key,
DataSizeMB,
Time,
MBps);
}
UE_LOG(LogVirtualization, Log, TEXT("======================================================================================="));
}
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
if (PushStats.Num() > 0)
{
UE_LOG(LogVirtualization, Log, TEXT("%-40s|%17s|%12s|%14s|"), TEXT("Pushing Data"), TEXT("TotalSize (MB)"), TEXT("TotalTime(s)"), TEXT("DataRate(MB/S)"));
UE_LOG(LogVirtualization, Log, TEXT("----------------------------------------|-----------------|------------|--------------|"));
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
for (const auto& Iterator : PushStats)
{
const double Time = Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Cycles) * FPlatformTime::GetSecondsPerCycle();
const int64 DataSizeMB = Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Bytes) / (1024 * 1024);
const double MBps = Time != 0.0 ? (DataSizeMB / Time) : 0.0;
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
UE_LOG(LogVirtualization, Log, TEXT("%-40.40s|%17" UINT64_FMT "|%12.3f|%14.3f|"),
*Iterator.Key,
DataSizeMB,
Time,
MBps);
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
}
UE_LOG(LogVirtualization, Log, TEXT("======================================================================================="));
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
}
if (PullStats.Num() > 0)
{
UE_LOG(LogVirtualization, Log, TEXT("%-40s|%17s|%12s|%14s|"), TEXT("Pulling Data"), TEXT("TotalSize (MB)"), TEXT("TotalTime(s)"), TEXT("DataRate(MB/S)"));
UE_LOG(LogVirtualization, Log, TEXT("----------------------------------------|-----------------|------------|--------------|"));
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
for (const auto& Iterator : PullStats)
{
const double Time = Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Cycles) * FPlatformTime::GetSecondsPerCycle();
const int64 DataSizeMB = Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Bytes) / (1024 * 1024);
const double MBps = Time != 0.0 ? (DataSizeMB / Time) : 0.0;
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
UE_LOG(LogVirtualization, Log, TEXT("%-40.40s|%17" UINT64_FMT "|%12.3f|%14.3f|"),
*Iterator.Key,
DataSizeMB,
Time,
MBps);
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
}
UE_LOG(LogVirtualization, Log, TEXT("======================================================================================="));
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
}
}
#endif // ENABLE_COOK_STATS
} //namespace Profiling
FVirtualizationManager::FVirtualizationManager()
: bEnablePayloadPushing(true)
, bEnableCacheAfterPull(true)
, MinPayloadLength(0)
, BackendGraphName(TEXT("ContentVirtualizationBackendGraph_None"))
{
Allow the virtualization of assets to be opt in, as well as opt out. This would allow a project to selectively turn on virtualization for specific locations or plugins rather than for the whole project by default. #rb PJ.Kack #jira UE-133473 #preflight 620bf6ae483ff0ae5ec22257 ### VirtualizationManager - Added EPackageFilterMode that can be set via [Core.ContentVirtualization] in the config file to control the default virtualization behavior. -- When set to EPackageFilterMode::OptOut(the default) all package paths will virtualize unless excluded by a pattern in UVirtualizationFilterSettings::ExcludePackagePaths. -- When set to EPackageFilterMode::OptIn then no package path will virtualize unless included by a pattern in UVirtualizationFilterSettings::IncludePackagePaths. - Added a TRACE_CPUPROFILER_EVENT_SCOPE to the constructor and ::MountBackends to better track the set up time costs. - Change use of FConfigCacheIni::LoadLocalIniFile to use GConfig, there is no need to load our own. - Improved verbose logging to show when a payload is rejected via filtering. - We now early out if all payloads being requested in a push are rejected during validation. - Renamed the FString overload for ::ShouldVirtualizePackage to ::ShouldVirtualize to make the difference clearer. - Added support for UVirtualizationFilterSettings::ExcludePackagePaths when filtering ### UVirtualizationFilterSettings - Now has a new FString array ExcludePackagePaths, which contains the paths/patterns used to force packages to be virtualized when filtering. [CL 19010992 by paul chipchase in ue5-main branch]
2022-02-16 01:27:09 -05:00
TRACE_CPUPROFILER_EVENT_SCOPE(FVirtualizationManager::FVirtualizationManager);
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
// Allows us to log the profiling data on process exit.
// TODO: We should just be able to call the logging in the destructor, but
// we need to fix the startup/shutdown ordering of Mirage first.
COOK_STAT(FCoreDelegates::OnExit.AddStatic(Profiling::LogStats));
}
FVirtualizationManager::~FVirtualizationManager()
{
UE_LOG(LogVirtualization, Log, TEXT("Destroying backends"));
for (IConsoleObject* ConsoleObject : DebugValues.ConsoleObjects)
{
IConsoleManager::Get().UnregisterConsoleObject(ConsoleObject);
}
LocalCachableBackends.Empty();
PersistentStorageBackends.Empty();
PullEnabledBackends.Empty();
AllBackends.Empty(); // This will delete all backends and beyond this point all references to them are invalid
UE_LOG(LogVirtualization, Log, TEXT("Virtualization manager destroyed"));
}
bool FVirtualizationManager::Initialize(const FInitParams& InitParams)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FVirtualizationManager::Initialize);
ProjectName = InitParams.ProjectName;
ApplySettingsFromConfigFiles(InitParams.ConfigFile);
ApplyDebugSettingsFromFromCmdline();
// Do this after all of the command line settings have been processed and any
// requested debug value changes already set.
RegisterConsoleCommands();
MountBackends(InitParams.ConfigFile);
return true;
}
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
bool FVirtualizationManager::IsEnabled() const
{
return !AllBackends.IsEmpty();
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
}
bool FVirtualizationManager::IsPushingEnabled(EStorageType StorageType) const
{
if (!bEnablePayloadPushing)
{
return false;
}
switch (StorageType)
{
case EStorageType::Local:
return !LocalCachableBackends.IsEmpty();
break;
case EStorageType::Persistent:
return !PersistentStorageBackends.IsEmpty();
break;
default:
checkNoEntry();
return false;
break;
}
}
It is now possible to disable virtualization for all payloads owned by a specific asset type by adding the name of the asset to [Core.ContentVirtualization]DisabledAsset string array in the engine ini file. #rb Per.Larsson #rnx #jira UE-151377 #preflight 628364050039ea57a52d6989 ### Virtualization - [Core.ContentVirtualization] in the engine ini file now supports an array called 'DisabledAsset' which can be used to name asset types that should not virtualize their payloads. -- By default (in BaseEngine.ini) we have disabled the StaticMesh asset as we know it will crash if a payload is missing and the SoundWave asset as it still is pending testing. - This new way to disable virtualization is data driven. The older hard coded method has not been removed but will likely be reworked in a future submit. - Now when an editor bulkdata is adding it's payload to the package trailer builder during package save it will poll the virtualization system with a call to the new method ::IsDisabledForObject by passing in it's owner. -- If the owner is valid and was present in the 'DisabledAsset' array then the method will return true and the EPayloadFlags::DisableVirtualization flag will be applied. ### Package Trailer - The pre-existing functionality of enum EPayloadFilter has been moved to a new enum EPayloadStorageType as will only filter payloads based on their storage type. - EPayloadFilter has been modified to filter payloads based on functionality although at the moment the only thing it can filter for is to return payloads that can be virtualized, it is left for future expansion. - EPayloadFlags has been reduced to a uint16 with the remaining 2bytes being turned into a new member EPayloadFilterReason. - This new member allows us to record the exact reason why a payload is excluded from virtualization. If it is zero then the payload can virtualize, otherwise it will contain one or more reasons as to why it is being excluded. For this reason the enum is a bitfield. - Added overloads of ::GetPayloads and ::GetNumPayloads that take EPayloadFilter rather than a EPayloadStorageType - Added wrappers around all AccessMode types for FLookupTableEntry. - FPackageTrailerBuilder has been extended to take a EPayloadFilterReason so that the caller can already provide a reason why the payload cannot be virtualized. -- As a future peace of work this will probably be changed and we will ask the caller to pass in the owner UObject pointer instead and then we will process the filtering when building the package trailer to a) keep all of the filtering code in one place b) keep the filtering consistent ### PackageSubmissionChecks - The virtualization process in will now request the payloads that can be virtualized from the package trailer, which respects the new payload flag, rather than requesting all locally stored payloads. ### UObjects - There is no need for the SoundWave or MeshDescription classes to opt out of virtualization on construction. This will be done when the package is saved and is now data driven rather than being hardcoded. ### DumpPackagePayloadInfo - The command has been updated to also display the filter reasons applied to each payload [CL 20240971 by paul chipchase in ue5-main branch]
2022-05-17 07:54:28 -04:00
bool FVirtualizationManager::IsDisabledForObject(const UObject* OwnerObject) const
{
if (OwnerObject == nullptr)
{
return false;
}
const UClass* OwnerClass = OwnerObject->GetClass();
if (OwnerClass == nullptr)
{
// TODO: Not actually sure if the class being nullptr is reasonable or if we should warn/error here?
return false;
}
FName ClassName = OwnerClass->GetFName();
return DisabledAssetTypes.Find(ClassName) != nullptr;
}
bool FVirtualizationManager::PushData(const FIoHash& Id, const FCompressedBuffer& Payload, EStorageType StorageType, const FString& Context)
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
{
FPushRequest Request(Id, Payload, Context);
return FVirtualizationManager::PushData(MakeArrayView(&Request, 1), StorageType);
}
bool FVirtualizationManager::PushData(TArrayView<FPushRequest> Requests, EStorageType StorageType)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FVirtualizationManager::PushData);
if (Requests.IsEmpty())
{
return true;
}
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
TArray<FPushRequest> ValidatedRequests;
ValidatedRequests.Reserve(Requests.Num());
TArray<int32> OriginalToValidatedRequest; // Builds a mapping between Requests and ValidatedRequests for later
OriginalToValidatedRequest.SetNum(Requests.Num());
// Create a new list of FPushRequest, excluding the requests that should not be processed for what ever reason.
for (int32 Index = 0; Index < Requests.Num(); ++Index)
{
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
OriginalToValidatedRequest[Index] = INDEX_NONE;
FPushRequest& Request = Requests[Index];
When virtualizing payloads we now load the payloads from disk on demand rather than all at once. This allows us to avoid memory spikes when virtualizing large amounts of data. #rb Per.Larsson #rnx #jira UE-151000 #preflight 627271c83b2ed6f85363f53a - In the old code when submitting packages for virtualization we would load all local payloads into memory then pass them to the virtualization system to be pushed to persistent storage. This works fine for an average users submits but when resaving large projects we can have submits with thousands of packages containing gigabytes of payloads. - FPushRequest has been changed to accept either a payload directly (in the form of FCompressedBuffer) or accept a reference to a IPayloadProvider which will return the payload when asked. - Most of the existing backends make no use of the batched pushing feature and only push one payload at a time. The default implementation of this will be to ask each request one at a time for the payload and then pass it to the backend for a single push. If the IPayloadProvider is being used we will therefor only ever have one payload loaded at a time avoiding memory spikes. - The source control backend currently does implement the batched pushing feature. This backend writes each payload to disk before submitting them to perforce, so all we have to do is make sure that request one payload, write it to disk, then discard the payload to avoid memory spikes. - This change required that FPushRequest make it's members private and provide accessors to them, as the caller shouldn't need to care if the payload is loaded or comes via the provider. - NOTE that this implementation is less efficient if we have packages containing many different payloads as we will end up opening the package, parsing the trailer then load a payload many times over, where as the original code would load all payloads from the file in one go. In practice, given the overhead of the source control backend this didn't make a huge difference and is probably not worth the effort to optimize at this point. [CL 20040609 by paul chipchase in ue5-main branch]
2022-05-04 08:58:50 -04:00
if (Request.GetIdentifier().IsZero() || Request.GetPayloadSize() == 0)
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
{
When virtualizing payloads we now load the payloads from disk on demand rather than all at once. This allows us to avoid memory spikes when virtualizing large amounts of data. #rb Per.Larsson #rnx #jira UE-151000 #preflight 627271c83b2ed6f85363f53a - In the old code when submitting packages for virtualization we would load all local payloads into memory then pass them to the virtualization system to be pushed to persistent storage. This works fine for an average users submits but when resaving large projects we can have submits with thousands of packages containing gigabytes of payloads. - FPushRequest has been changed to accept either a payload directly (in the form of FCompressedBuffer) or accept a reference to a IPayloadProvider which will return the payload when asked. - Most of the existing backends make no use of the batched pushing feature and only push one payload at a time. The default implementation of this will be to ask each request one at a time for the payload and then pass it to the backend for a single push. If the IPayloadProvider is being used we will therefor only ever have one payload loaded at a time avoiding memory spikes. - The source control backend currently does implement the batched pushing feature. This backend writes each payload to disk before submitting them to perforce, so all we have to do is make sure that request one payload, write it to disk, then discard the payload to avoid memory spikes. - This change required that FPushRequest make it's members private and provide accessors to them, as the caller shouldn't need to care if the payload is loaded or comes via the provider. - NOTE that this implementation is less efficient if we have packages containing many different payloads as we will end up opening the package, parsing the trailer then load a payload many times over, where as the original code would load all payloads from the file in one go. In practice, given the overhead of the source control backend this didn't make a huge difference and is probably not worth the effort to optimize at this point. [CL 20040609 by paul chipchase in ue5-main branch]
2022-05-04 08:58:50 -04:00
Request.SetStatus(FPushRequest::EStatus::Invalid);
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
continue;
}
When virtualizing payloads we now load the payloads from disk on demand rather than all at once. This allows us to avoid memory spikes when virtualizing large amounts of data. #rb Per.Larsson #rnx #jira UE-151000 #preflight 627271c83b2ed6f85363f53a - In the old code when submitting packages for virtualization we would load all local payloads into memory then pass them to the virtualization system to be pushed to persistent storage. This works fine for an average users submits but when resaving large projects we can have submits with thousands of packages containing gigabytes of payloads. - FPushRequest has been changed to accept either a payload directly (in the form of FCompressedBuffer) or accept a reference to a IPayloadProvider which will return the payload when asked. - Most of the existing backends make no use of the batched pushing feature and only push one payload at a time. The default implementation of this will be to ask each request one at a time for the payload and then pass it to the backend for a single push. If the IPayloadProvider is being used we will therefor only ever have one payload loaded at a time avoiding memory spikes. - The source control backend currently does implement the batched pushing feature. This backend writes each payload to disk before submitting them to perforce, so all we have to do is make sure that request one payload, write it to disk, then discard the payload to avoid memory spikes. - This change required that FPushRequest make it's members private and provide accessors to them, as the caller shouldn't need to care if the payload is loaded or comes via the provider. - NOTE that this implementation is less efficient if we have packages containing many different payloads as we will end up opening the package, parsing the trailer then load a payload many times over, where as the original code would load all payloads from the file in one go. In practice, given the overhead of the source control backend this didn't make a huge difference and is probably not worth the effort to optimize at this point. [CL 20040609 by paul chipchase in ue5-main branch]
2022-05-04 08:58:50 -04:00
if ((int64)Request.GetPayloadSize() < MinPayloadLength)
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
{
UE_LOG( LogVirtualization, Verbose, TEXT("Pushing payload (id: %s) with context ('%s') was prevented as it is smaller (%" UINT64_FMT ") than the MinPayloadLength (%" INT64_FMT ")"),
When virtualizing payloads we now load the payloads from disk on demand rather than all at once. This allows us to avoid memory spikes when virtualizing large amounts of data. #rb Per.Larsson #rnx #jira UE-151000 #preflight 627271c83b2ed6f85363f53a - In the old code when submitting packages for virtualization we would load all local payloads into memory then pass them to the virtualization system to be pushed to persistent storage. This works fine for an average users submits but when resaving large projects we can have submits with thousands of packages containing gigabytes of payloads. - FPushRequest has been changed to accept either a payload directly (in the form of FCompressedBuffer) or accept a reference to a IPayloadProvider which will return the payload when asked. - Most of the existing backends make no use of the batched pushing feature and only push one payload at a time. The default implementation of this will be to ask each request one at a time for the payload and then pass it to the backend for a single push. If the IPayloadProvider is being used we will therefor only ever have one payload loaded at a time avoiding memory spikes. - The source control backend currently does implement the batched pushing feature. This backend writes each payload to disk before submitting them to perforce, so all we have to do is make sure that request one payload, write it to disk, then discard the payload to avoid memory spikes. - This change required that FPushRequest make it's members private and provide accessors to them, as the caller shouldn't need to care if the payload is loaded or comes via the provider. - NOTE that this implementation is less efficient if we have packages containing many different payloads as we will end up opening the package, parsing the trailer then load a payload many times over, where as the original code would load all payloads from the file in one go. In practice, given the overhead of the source control backend this didn't make a huge difference and is probably not worth the effort to optimize at this point. [CL 20040609 by paul chipchase in ue5-main branch]
2022-05-04 08:58:50 -04:00
*LexToString(Request.GetIdentifier()),
*Request.GetContext(),
Request.GetPayloadSize(),
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
MinPayloadLength);
When virtualizing payloads we now load the payloads from disk on demand rather than all at once. This allows us to avoid memory spikes when virtualizing large amounts of data. #rb Per.Larsson #rnx #jira UE-151000 #preflight 627271c83b2ed6f85363f53a - In the old code when submitting packages for virtualization we would load all local payloads into memory then pass them to the virtualization system to be pushed to persistent storage. This works fine for an average users submits but when resaving large projects we can have submits with thousands of packages containing gigabytes of payloads. - FPushRequest has been changed to accept either a payload directly (in the form of FCompressedBuffer) or accept a reference to a IPayloadProvider which will return the payload when asked. - Most of the existing backends make no use of the batched pushing feature and only push one payload at a time. The default implementation of this will be to ask each request one at a time for the payload and then pass it to the backend for a single push. If the IPayloadProvider is being used we will therefor only ever have one payload loaded at a time avoiding memory spikes. - The source control backend currently does implement the batched pushing feature. This backend writes each payload to disk before submitting them to perforce, so all we have to do is make sure that request one payload, write it to disk, then discard the payload to avoid memory spikes. - This change required that FPushRequest make it's members private and provide accessors to them, as the caller shouldn't need to care if the payload is loaded or comes via the provider. - NOTE that this implementation is less efficient if we have packages containing many different payloads as we will end up opening the package, parsing the trailer then load a payload many times over, where as the original code would load all payloads from the file in one go. In practice, given the overhead of the source control backend this didn't make a huge difference and is probably not worth the effort to optimize at this point. [CL 20040609 by paul chipchase in ue5-main branch]
2022-05-04 08:58:50 -04:00
Request.SetStatus(FPushRequest::EStatus::BelowMinSize);
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
continue;
}
When virtualizing payloads we now load the payloads from disk on demand rather than all at once. This allows us to avoid memory spikes when virtualizing large amounts of data. #rb Per.Larsson #rnx #jira UE-151000 #preflight 627271c83b2ed6f85363f53a - In the old code when submitting packages for virtualization we would load all local payloads into memory then pass them to the virtualization system to be pushed to persistent storage. This works fine for an average users submits but when resaving large projects we can have submits with thousands of packages containing gigabytes of payloads. - FPushRequest has been changed to accept either a payload directly (in the form of FCompressedBuffer) or accept a reference to a IPayloadProvider which will return the payload when asked. - Most of the existing backends make no use of the batched pushing feature and only push one payload at a time. The default implementation of this will be to ask each request one at a time for the payload and then pass it to the backend for a single push. If the IPayloadProvider is being used we will therefor only ever have one payload loaded at a time avoiding memory spikes. - The source control backend currently does implement the batched pushing feature. This backend writes each payload to disk before submitting them to perforce, so all we have to do is make sure that request one payload, write it to disk, then discard the payload to avoid memory spikes. - This change required that FPushRequest make it's members private and provide accessors to them, as the caller shouldn't need to care if the payload is loaded or comes via the provider. - NOTE that this implementation is less efficient if we have packages containing many different payloads as we will end up opening the package, parsing the trailer then load a payload many times over, where as the original code would load all payloads from the file in one go. In practice, given the overhead of the source control backend this didn't make a huge difference and is probably not worth the effort to optimize at this point. [CL 20040609 by paul chipchase in ue5-main branch]
2022-05-04 08:58:50 -04:00
if (!ShouldVirtualize(Request.GetContext()))
{
Allow the virtualization of assets to be opt in, as well as opt out. This would allow a project to selectively turn on virtualization for specific locations or plugins rather than for the whole project by default. #rb PJ.Kack #jira UE-133473 #preflight 620bf6ae483ff0ae5ec22257 ### VirtualizationManager - Added EPackageFilterMode that can be set via [Core.ContentVirtualization] in the config file to control the default virtualization behavior. -- When set to EPackageFilterMode::OptOut(the default) all package paths will virtualize unless excluded by a pattern in UVirtualizationFilterSettings::ExcludePackagePaths. -- When set to EPackageFilterMode::OptIn then no package path will virtualize unless included by a pattern in UVirtualizationFilterSettings::IncludePackagePaths. - Added a TRACE_CPUPROFILER_EVENT_SCOPE to the constructor and ::MountBackends to better track the set up time costs. - Change use of FConfigCacheIni::LoadLocalIniFile to use GConfig, there is no need to load our own. - Improved verbose logging to show when a payload is rejected via filtering. - We now early out if all payloads being requested in a push are rejected during validation. - Renamed the FString overload for ::ShouldVirtualizePackage to ::ShouldVirtualize to make the difference clearer. - Added support for UVirtualizationFilterSettings::ExcludePackagePaths when filtering ### UVirtualizationFilterSettings - Now has a new FString array ExcludePackagePaths, which contains the paths/patterns used to force packages to be virtualized when filtering. [CL 19010992 by paul chipchase in ue5-main branch]
2022-02-16 01:27:09 -05:00
UE_LOG( LogVirtualization, Verbose, TEXT("Pushing payload (id: %s) with context ('%s') was prevented by filtering"),
When virtualizing payloads we now load the payloads from disk on demand rather than all at once. This allows us to avoid memory spikes when virtualizing large amounts of data. #rb Per.Larsson #rnx #jira UE-151000 #preflight 627271c83b2ed6f85363f53a - In the old code when submitting packages for virtualization we would load all local payloads into memory then pass them to the virtualization system to be pushed to persistent storage. This works fine for an average users submits but when resaving large projects we can have submits with thousands of packages containing gigabytes of payloads. - FPushRequest has been changed to accept either a payload directly (in the form of FCompressedBuffer) or accept a reference to a IPayloadProvider which will return the payload when asked. - Most of the existing backends make no use of the batched pushing feature and only push one payload at a time. The default implementation of this will be to ask each request one at a time for the payload and then pass it to the backend for a single push. If the IPayloadProvider is being used we will therefor only ever have one payload loaded at a time avoiding memory spikes. - The source control backend currently does implement the batched pushing feature. This backend writes each payload to disk before submitting them to perforce, so all we have to do is make sure that request one payload, write it to disk, then discard the payload to avoid memory spikes. - This change required that FPushRequest make it's members private and provide accessors to them, as the caller shouldn't need to care if the payload is loaded or comes via the provider. - NOTE that this implementation is less efficient if we have packages containing many different payloads as we will end up opening the package, parsing the trailer then load a payload many times over, where as the original code would load all payloads from the file in one go. In practice, given the overhead of the source control backend this didn't make a huge difference and is probably not worth the effort to optimize at this point. [CL 20040609 by paul chipchase in ue5-main branch]
2022-05-04 08:58:50 -04:00
*LexToString(Request.GetIdentifier()),
*Request.GetContext());
When virtualizing payloads we now load the payloads from disk on demand rather than all at once. This allows us to avoid memory spikes when virtualizing large amounts of data. #rb Per.Larsson #rnx #jira UE-151000 #preflight 627271c83b2ed6f85363f53a - In the old code when submitting packages for virtualization we would load all local payloads into memory then pass them to the virtualization system to be pushed to persistent storage. This works fine for an average users submits but when resaving large projects we can have submits with thousands of packages containing gigabytes of payloads. - FPushRequest has been changed to accept either a payload directly (in the form of FCompressedBuffer) or accept a reference to a IPayloadProvider which will return the payload when asked. - Most of the existing backends make no use of the batched pushing feature and only push one payload at a time. The default implementation of this will be to ask each request one at a time for the payload and then pass it to the backend for a single push. If the IPayloadProvider is being used we will therefor only ever have one payload loaded at a time avoiding memory spikes. - The source control backend currently does implement the batched pushing feature. This backend writes each payload to disk before submitting them to perforce, so all we have to do is make sure that request one payload, write it to disk, then discard the payload to avoid memory spikes. - This change required that FPushRequest make it's members private and provide accessors to them, as the caller shouldn't need to care if the payload is loaded or comes via the provider. - NOTE that this implementation is less efficient if we have packages containing many different payloads as we will end up opening the package, parsing the trailer then load a payload many times over, where as the original code would load all payloads from the file in one go. In practice, given the overhead of the source control backend this didn't make a huge difference and is probably not worth the effort to optimize at this point. [CL 20040609 by paul chipchase in ue5-main branch]
2022-05-04 08:58:50 -04:00
Request.SetStatus(FPushRequest::EStatus::ExcludedByPackagPath);
continue;
}
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
OriginalToValidatedRequest[Index] = ValidatedRequests.Num();
ValidatedRequests.Add(Request);
}
Allow the virtualization of assets to be opt in, as well as opt out. This would allow a project to selectively turn on virtualization for specific locations or plugins rather than for the whole project by default. #rb PJ.Kack #jira UE-133473 #preflight 620bf6ae483ff0ae5ec22257 ### VirtualizationManager - Added EPackageFilterMode that can be set via [Core.ContentVirtualization] in the config file to control the default virtualization behavior. -- When set to EPackageFilterMode::OptOut(the default) all package paths will virtualize unless excluded by a pattern in UVirtualizationFilterSettings::ExcludePackagePaths. -- When set to EPackageFilterMode::OptIn then no package path will virtualize unless included by a pattern in UVirtualizationFilterSettings::IncludePackagePaths. - Added a TRACE_CPUPROFILER_EVENT_SCOPE to the constructor and ::MountBackends to better track the set up time costs. - Change use of FConfigCacheIni::LoadLocalIniFile to use GConfig, there is no need to load our own. - Improved verbose logging to show when a payload is rejected via filtering. - We now early out if all payloads being requested in a push are rejected during validation. - Renamed the FString overload for ::ShouldVirtualizePackage to ::ShouldVirtualize to make the difference clearer. - Added support for UVirtualizationFilterSettings::ExcludePackagePaths when filtering ### UVirtualizationFilterSettings - Now has a new FString array ExcludePackagePaths, which contains the paths/patterns used to force packages to be virtualized when filtering. [CL 19010992 by paul chipchase in ue5-main branch]
2022-02-16 01:27:09 -05:00
// Early out if none of the requests require pushing after validation
if (ValidatedRequests.IsEmpty())
{
return true;
}
// Early out if there are no backends
if (!IsEnabled() || bEnablePayloadPushing == false)
{
return false;
}
FConditionalScopeLock _(&DebugValues.ForceSingleThreadedCS, DebugValues.bSingleThreaded);
// TODO: Note that all push operations are currently synchronous, probably
// should change to async at some point, although this makes handling failed
// pushed much more difficult.
int32 ErrorCount = 0;
bool bWasPayloadPushed = false;
FBackendArray& Backends = StorageType == EStorageType::Local ? LocalCachableBackends : PersistentStorageBackends;
for (IVirtualizationBackend* Backend : Backends)
{
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
const bool bResult = TryPushDataToBackend(*Backend, ValidatedRequests);
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
UE_CLOG(bResult == true, LogVirtualization, Verbose, TEXT("[%s] Pushed '%d' payload(s)"), *Backend->GetDebugName(), ValidatedRequests.Num());
UE_CLOG(bResult == false, LogVirtualization, Error, TEXT("[%s] Failed to push '%d' payload(s)"), *Backend->GetDebugName(), ValidatedRequests.Num());
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
if (!bResult)
{
ErrorCount++;
}
// Debug operation to validate that the payload we just pushed can be retrieved from storage
if (DebugValues.bValidateAfterPush && bResult == true && Backend->IsOperationSupported(IVirtualizationBackend::EOperations::Pull))
{
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
for (FPushRequest& Request : ValidatedRequests)
{
When virtualizing payloads we now load the payloads from disk on demand rather than all at once. This allows us to avoid memory spikes when virtualizing large amounts of data. #rb Per.Larsson #rnx #jira UE-151000 #preflight 627271c83b2ed6f85363f53a - In the old code when submitting packages for virtualization we would load all local payloads into memory then pass them to the virtualization system to be pushed to persistent storage. This works fine for an average users submits but when resaving large projects we can have submits with thousands of packages containing gigabytes of payloads. - FPushRequest has been changed to accept either a payload directly (in the form of FCompressedBuffer) or accept a reference to a IPayloadProvider which will return the payload when asked. - Most of the existing backends make no use of the batched pushing feature and only push one payload at a time. The default implementation of this will be to ask each request one at a time for the payload and then pass it to the backend for a single push. If the IPayloadProvider is being used we will therefor only ever have one payload loaded at a time avoiding memory spikes. - The source control backend currently does implement the batched pushing feature. This backend writes each payload to disk before submitting them to perforce, so all we have to do is make sure that request one payload, write it to disk, then discard the payload to avoid memory spikes. - This change required that FPushRequest make it's members private and provide accessors to them, as the caller shouldn't need to care if the payload is loaded or comes via the provider. - NOTE that this implementation is less efficient if we have packages containing many different payloads as we will end up opening the package, parsing the trailer then load a payload many times over, where as the original code would load all payloads from the file in one go. In practice, given the overhead of the source control backend this didn't make a huge difference and is probably not worth the effort to optimize at this point. [CL 20040609 by paul chipchase in ue5-main branch]
2022-05-04 08:58:50 -04:00
FCompressedBuffer ValidationPayload = PullDataFromBackend(*Backend, Request.GetIdentifier());
checkf( Request.GetIdentifier() == ValidationPayload.GetRawHash(),
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
TEXT("[%s] Failed to pull payload '%s' after it was pushed to backend"),
*Backend->GetDebugName(),
When virtualizing payloads we now load the payloads from disk on demand rather than all at once. This allows us to avoid memory spikes when virtualizing large amounts of data. #rb Per.Larsson #rnx #jira UE-151000 #preflight 627271c83b2ed6f85363f53a - In the old code when submitting packages for virtualization we would load all local payloads into memory then pass them to the virtualization system to be pushed to persistent storage. This works fine for an average users submits but when resaving large projects we can have submits with thousands of packages containing gigabytes of payloads. - FPushRequest has been changed to accept either a payload directly (in the form of FCompressedBuffer) or accept a reference to a IPayloadProvider which will return the payload when asked. - Most of the existing backends make no use of the batched pushing feature and only push one payload at a time. The default implementation of this will be to ask each request one at a time for the payload and then pass it to the backend for a single push. If the IPayloadProvider is being used we will therefor only ever have one payload loaded at a time avoiding memory spikes. - The source control backend currently does implement the batched pushing feature. This backend writes each payload to disk before submitting them to perforce, so all we have to do is make sure that request one payload, write it to disk, then discard the payload to avoid memory spikes. - This change required that FPushRequest make it's members private and provide accessors to them, as the caller shouldn't need to care if the payload is loaded or comes via the provider. - NOTE that this implementation is less efficient if we have packages containing many different payloads as we will end up opening the package, parsing the trailer then load a payload many times over, where as the original code would load all payloads from the file in one go. In practice, given the overhead of the source control backend this didn't make a huge difference and is probably not worth the effort to optimize at this point. [CL 20040609 by paul chipchase in ue5-main branch]
2022-05-04 08:58:50 -04:00
*LexToString(Request.GetIdentifier()));
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
}
}
}
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
UE_CLOG(ErrorCount == Backends.Num(), LogVirtualization, Error, TEXT("Failed to push '%d' payload(s) to any backend'"), ValidatedRequests.Num());
// Now we need to update the statuses of the original list of requests with those from our validated list
for (int32 Index = 0; Index < Requests.Num(); ++Index)
{
const int32 MappingIndex = OriginalToValidatedRequest[Index];
if (MappingIndex != INDEX_NONE)
{
When virtualizing payloads we now load the payloads from disk on demand rather than all at once. This allows us to avoid memory spikes when virtualizing large amounts of data. #rb Per.Larsson #rnx #jira UE-151000 #preflight 627271c83b2ed6f85363f53a - In the old code when submitting packages for virtualization we would load all local payloads into memory then pass them to the virtualization system to be pushed to persistent storage. This works fine for an average users submits but when resaving large projects we can have submits with thousands of packages containing gigabytes of payloads. - FPushRequest has been changed to accept either a payload directly (in the form of FCompressedBuffer) or accept a reference to a IPayloadProvider which will return the payload when asked. - Most of the existing backends make no use of the batched pushing feature and only push one payload at a time. The default implementation of this will be to ask each request one at a time for the payload and then pass it to the backend for a single push. If the IPayloadProvider is being used we will therefor only ever have one payload loaded at a time avoiding memory spikes. - The source control backend currently does implement the batched pushing feature. This backend writes each payload to disk before submitting them to perforce, so all we have to do is make sure that request one payload, write it to disk, then discard the payload to avoid memory spikes. - This change required that FPushRequest make it's members private and provide accessors to them, as the caller shouldn't need to care if the payload is loaded or comes via the provider. - NOTE that this implementation is less efficient if we have packages containing many different payloads as we will end up opening the package, parsing the trailer then load a payload many times over, where as the original code would load all payloads from the file in one go. In practice, given the overhead of the source control backend this didn't make a huge difference and is probably not worth the effort to optimize at this point. [CL 20040609 by paul chipchase in ue5-main branch]
2022-05-04 08:58:50 -04:00
Requests[Index].SetStatus(ValidatedRequests[MappingIndex].GetStatus());
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
}
}
// For local storage we consider the push to have failed only if ALL backends gave an error, if at least one backend succeeded then the operation succeeded.
// For persistent storage we require that all backends succeeded, so any errors will fail the push operation.
return StorageType == EStorageType::Local ? ErrorCount < Backends.Num() : ErrorCount == 0;
}
FCompressedBuffer FVirtualizationManager::PullData(const FIoHash& Id)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FVirtualizationManager::PullData);
if (Id.IsZero())
{
// TODO: See below, should errors here be fatal?
UE_LOG(LogVirtualization, Error, TEXT("Attempting to pull a virtualized payload with an invalid FIoHash"));
return FCompressedBuffer();
}
if (PullEnabledBackends.IsEmpty())
{
// TODO: See below, should errors here be fatal?
UE_LOG(LogVirtualization, Error, TEXT("Payload '%s' failed to be pulled as there are no backends mounted!'"), *LexToString(Id));
return FCompressedBuffer();
}
FConditionalScopeLock _(&DebugValues.ForceSingleThreadedCS, DebugValues.bSingleThreaded);
GetNotificationEvent().Broadcast(IVirtualizationSystem::PullBegunNotification, Id);
FCompressedBuffer Payload = PullDataFromAllBackends(Id);
GetNotificationEvent().Broadcast(IVirtualizationSystem::PullEndedNotification, Id);
if (!Payload.IsNull())
{
return Payload;
}
else
{
// Broadcast the pull failed event to any listeners
GetNotificationEvent().Broadcast(IVirtualizationSystem::PullFailedNotification, Id);
// TODO: Maybe this should be a fatal error? If we keep it as an error we need to make sure any calling
// code handles it properly.
// Could be worth extending ::PullData to return error codes instead so we can make a better distinction
// between the payload not being found in any of the backends and one or more of the backends failing.
UE_LOG(LogVirtualization, Error, TEXT("Payload '%s' failed to be pulled from any backend'"), *LexToString(Id));
return FCompressedBuffer();
}
}
EQueryResult FVirtualizationManager::QueryPayloadStatuses(TArrayView<const FIoHash> Ids, EStorageType StorageType, TArray<FPayloadStatus>& OutStatuses)
Submitting packages on projects with virtualization enabled is much faster when none of the payloads actually needs to be virtualized. #rb PJ.Kack #rnx #preflight 61a795773c29b3cf13cd8250 ### PackageSubmissionChecks - Under the old model submitting a large number of packages could be very slow as each package would check each payload that it owns and is currently stored locally one at a time. For the source control backend this created quite a large overhead even when all of the payloads were already virtualized. - Now we do a pass over the submitted files to find all valid packages that have package trailers with locally stored payloads, gather the payloads into a single list and then query that in one large batch. - Once we find which payloads are not in permanent storage (note that in the case where a project is using multiple permanent storage solutions, if a payload is missing in one backend it counts as not being in permanent storage) we then attempt to virtualized them. - Only after all of this is done will we create the truncated copy of each package and then append the updated trailer to each one. In theory doing it in this order this might slightly increase the change of submit failures that occur after virtualization that result in a package never being submitted and orphaned payloads being added to permanent storage, but this will always be a risk. - Added an assert to fire if we detect a trailer with some virtualized and some local payloads. This should be a supported feature but needs proper testing first before we can allow it. With out current project settings no project should actually encounter this scenario. - To make the code easier to follow we now early out of the entire check when errors are encountered. - Added logging at various stages in the process to help show the user that something is happening and make problems easier to identify in the future. - Notes -- There is a lot of handling of invalid FPayloads. This is because it is currently possible to add empty payloads to the trailer which is inefficient and wastes space. The trailer will be modified to reject empty payloads in a future update at which point a lot of this handling can be removed. -- This could've also been solved by not fully rehydrating a package on save by the end user, which will be added as a project setting in a future piece of work, but this approach will solve the edge case when the user does have a large amount of hydrated packages which contain payloads that are already virtualized so it was better to fix that now while we have good test cases for it. -- We still have scaling problems with large number of package being submitted that do have payloads that need to be virtualized, this will be fixed by extending IVirtualizationSystem::Push to also accept batches of payloads in future work. -- OnPrePackageSubmission could be broken up into smaller chunks to make the code easier to follow. This will be done after the batch payload submission work is done. ### VirtualizationSystem - EStorageType has been promoted to enum class. - Added a new enum FPayloadStatus to be used when querying if a payload exists in a backend storage system or not. - Add a new method ::DoPayloadsExist which allows the caller to query if one or more payloads exists in the given backend storage system. ### VirtualizationManager - Implemented ::DoPayloadsExist. First we get the results from each backend in the storage system (which return as true or false from each backend) then total how many backends found the payload in order to set the correct status. ### IVirtualizationBackend - ::DoesPayloadExist which queries the existence of a single payload has been added to the interface. Most backends already implemented this for private use and if so have had their implementation renamed to match this. - Also added ::DoPayloadsExist which takes a batch of FpayloadIdsto query. Some backends can deal with a batch of payload ids much more efficiently than one at a time, although the default implementation does call ::DoesPayloadExist for each requested payload. -- The default implementation prevents every backend from needing to implement the same for loop but does allow backends that can gain from batching to override it. ### VirtualizationSourceControlBackend - This backend does override ::DoPayloadsExist and implements it's own version as it tends to perform very poorly when not operating on larger batches. - In this case ::DoesPayloadExist calls back to ::DoPayloadsExist to check each payload rather than implement as specific version. ### PackageTrailer - The trailer can now be queries to request how many payloads of a given type it contains #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18339847 in //UE5/Release-5.0/... via CL 18339852 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v895-18170469) [CL 18339859 by paul chipchase in ue5-release-engine-test branch]
2021-12-01 11:13:31 -05:00
{
TRACE_CPUPROFILER_EVENT_SCOPE(FVirtualizationManager::DoPayloadsExist);
OutStatuses.SetNum(Ids.Num()); // Make sure we set the number out statuses before we potentially early out
if (Ids.IsEmpty())
{
return EQueryResult::Success;
}
Submitting packages on projects with virtualization enabled is much faster when none of the payloads actually needs to be virtualized. #rb PJ.Kack #rnx #preflight 61a795773c29b3cf13cd8250 ### PackageSubmissionChecks - Under the old model submitting a large number of packages could be very slow as each package would check each payload that it owns and is currently stored locally one at a time. For the source control backend this created quite a large overhead even when all of the payloads were already virtualized. - Now we do a pass over the submitted files to find all valid packages that have package trailers with locally stored payloads, gather the payloads into a single list and then query that in one large batch. - Once we find which payloads are not in permanent storage (note that in the case where a project is using multiple permanent storage solutions, if a payload is missing in one backend it counts as not being in permanent storage) we then attempt to virtualized them. - Only after all of this is done will we create the truncated copy of each package and then append the updated trailer to each one. In theory doing it in this order this might slightly increase the change of submit failures that occur after virtualization that result in a package never being submitted and orphaned payloads being added to permanent storage, but this will always be a risk. - Added an assert to fire if we detect a trailer with some virtualized and some local payloads. This should be a supported feature but needs proper testing first before we can allow it. With out current project settings no project should actually encounter this scenario. - To make the code easier to follow we now early out of the entire check when errors are encountered. - Added logging at various stages in the process to help show the user that something is happening and make problems easier to identify in the future. - Notes -- There is a lot of handling of invalid FPayloads. This is because it is currently possible to add empty payloads to the trailer which is inefficient and wastes space. The trailer will be modified to reject empty payloads in a future update at which point a lot of this handling can be removed. -- This could've also been solved by not fully rehydrating a package on save by the end user, which will be added as a project setting in a future piece of work, but this approach will solve the edge case when the user does have a large amount of hydrated packages which contain payloads that are already virtualized so it was better to fix that now while we have good test cases for it. -- We still have scaling problems with large number of package being submitted that do have payloads that need to be virtualized, this will be fixed by extending IVirtualizationSystem::Push to also accept batches of payloads in future work. -- OnPrePackageSubmission could be broken up into smaller chunks to make the code easier to follow. This will be done after the batch payload submission work is done. ### VirtualizationSystem - EStorageType has been promoted to enum class. - Added a new enum FPayloadStatus to be used when querying if a payload exists in a backend storage system or not. - Add a new method ::DoPayloadsExist which allows the caller to query if one or more payloads exists in the given backend storage system. ### VirtualizationManager - Implemented ::DoPayloadsExist. First we get the results from each backend in the storage system (which return as true or false from each backend) then total how many backends found the payload in order to set the correct status. ### IVirtualizationBackend - ::DoesPayloadExist which queries the existence of a single payload has been added to the interface. Most backends already implemented this for private use and if so have had their implementation renamed to match this. - Also added ::DoPayloadsExist which takes a batch of FpayloadIdsto query. Some backends can deal with a batch of payload ids much more efficiently than one at a time, although the default implementation does call ::DoesPayloadExist for each requested payload. -- The default implementation prevents every backend from needing to implement the same for loop but does allow backends that can gain from batching to override it. ### VirtualizationSourceControlBackend - This backend does override ::DoPayloadsExist and implements it's own version as it tends to perform very poorly when not operating on larger batches. - In this case ::DoesPayloadExist calls back to ::DoPayloadsExist to check each payload rather than implement as specific version. ### PackageTrailer - The trailer can now be queries to request how many payloads of a given type it contains #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18339847 in //UE5/Release-5.0/... via CL 18339852 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v895-18170469) [CL 18339859 by paul chipchase in ue5-release-engine-test branch]
2021-12-01 11:13:31 -05:00
for (int32 Index = 0; Index < Ids.Num(); ++Index)
{
OutStatuses[Index] = Ids[Index].IsZero() ? FPayloadStatus::Invalid : FPayloadStatus::NotFound;
Submitting packages on projects with virtualization enabled is much faster when none of the payloads actually needs to be virtualized. #rb PJ.Kack #rnx #preflight 61a795773c29b3cf13cd8250 ### PackageSubmissionChecks - Under the old model submitting a large number of packages could be very slow as each package would check each payload that it owns and is currently stored locally one at a time. For the source control backend this created quite a large overhead even when all of the payloads were already virtualized. - Now we do a pass over the submitted files to find all valid packages that have package trailers with locally stored payloads, gather the payloads into a single list and then query that in one large batch. - Once we find which payloads are not in permanent storage (note that in the case where a project is using multiple permanent storage solutions, if a payload is missing in one backend it counts as not being in permanent storage) we then attempt to virtualized them. - Only after all of this is done will we create the truncated copy of each package and then append the updated trailer to each one. In theory doing it in this order this might slightly increase the change of submit failures that occur after virtualization that result in a package never being submitted and orphaned payloads being added to permanent storage, but this will always be a risk. - Added an assert to fire if we detect a trailer with some virtualized and some local payloads. This should be a supported feature but needs proper testing first before we can allow it. With out current project settings no project should actually encounter this scenario. - To make the code easier to follow we now early out of the entire check when errors are encountered. - Added logging at various stages in the process to help show the user that something is happening and make problems easier to identify in the future. - Notes -- There is a lot of handling of invalid FPayloads. This is because it is currently possible to add empty payloads to the trailer which is inefficient and wastes space. The trailer will be modified to reject empty payloads in a future update at which point a lot of this handling can be removed. -- This could've also been solved by not fully rehydrating a package on save by the end user, which will be added as a project setting in a future piece of work, but this approach will solve the edge case when the user does have a large amount of hydrated packages which contain payloads that are already virtualized so it was better to fix that now while we have good test cases for it. -- We still have scaling problems with large number of package being submitted that do have payloads that need to be virtualized, this will be fixed by extending IVirtualizationSystem::Push to also accept batches of payloads in future work. -- OnPrePackageSubmission could be broken up into smaller chunks to make the code easier to follow. This will be done after the batch payload submission work is done. ### VirtualizationSystem - EStorageType has been promoted to enum class. - Added a new enum FPayloadStatus to be used when querying if a payload exists in a backend storage system or not. - Add a new method ::DoPayloadsExist which allows the caller to query if one or more payloads exists in the given backend storage system. ### VirtualizationManager - Implemented ::DoPayloadsExist. First we get the results from each backend in the storage system (which return as true or false from each backend) then total how many backends found the payload in order to set the correct status. ### IVirtualizationBackend - ::DoesPayloadExist which queries the existence of a single payload has been added to the interface. Most backends already implemented this for private use and if so have had their implementation renamed to match this. - Also added ::DoPayloadsExist which takes a batch of FpayloadIdsto query. Some backends can deal with a batch of payload ids much more efficiently than one at a time, although the default implementation does call ::DoesPayloadExist for each requested payload. -- The default implementation prevents every backend from needing to implement the same for loop but does allow backends that can gain from batching to override it. ### VirtualizationSourceControlBackend - This backend does override ::DoPayloadsExist and implements it's own version as it tends to perform very poorly when not operating on larger batches. - In this case ::DoesPayloadExist calls back to ::DoPayloadsExist to check each payload rather than implement as specific version. ### PackageTrailer - The trailer can now be queries to request how many payloads of a given type it contains #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18339847 in //UE5/Release-5.0/... via CL 18339852 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v895-18170469) [CL 18339859 by paul chipchase in ue5-release-engine-test branch]
2021-12-01 11:13:31 -05:00
}
FBackendArray& Backends = StorageType == EStorageType::Local ? LocalCachableBackends : PersistentStorageBackends;
TArray<int8> HitCount;
TArray<bool> Results;
HitCount.SetNum(Ids.Num());
Results.SetNum(Ids.Num());
{
FConditionalScopeLock _(&DebugValues.ForceSingleThreadedCS, DebugValues.bSingleThreaded);
Submitting packages on projects with virtualization enabled is much faster when none of the payloads actually needs to be virtualized. #rb PJ.Kack #rnx #preflight 61a795773c29b3cf13cd8250 ### PackageSubmissionChecks - Under the old model submitting a large number of packages could be very slow as each package would check each payload that it owns and is currently stored locally one at a time. For the source control backend this created quite a large overhead even when all of the payloads were already virtualized. - Now we do a pass over the submitted files to find all valid packages that have package trailers with locally stored payloads, gather the payloads into a single list and then query that in one large batch. - Once we find which payloads are not in permanent storage (note that in the case where a project is using multiple permanent storage solutions, if a payload is missing in one backend it counts as not being in permanent storage) we then attempt to virtualized them. - Only after all of this is done will we create the truncated copy of each package and then append the updated trailer to each one. In theory doing it in this order this might slightly increase the change of submit failures that occur after virtualization that result in a package never being submitted and orphaned payloads being added to permanent storage, but this will always be a risk. - Added an assert to fire if we detect a trailer with some virtualized and some local payloads. This should be a supported feature but needs proper testing first before we can allow it. With out current project settings no project should actually encounter this scenario. - To make the code easier to follow we now early out of the entire check when errors are encountered. - Added logging at various stages in the process to help show the user that something is happening and make problems easier to identify in the future. - Notes -- There is a lot of handling of invalid FPayloads. This is because it is currently possible to add empty payloads to the trailer which is inefficient and wastes space. The trailer will be modified to reject empty payloads in a future update at which point a lot of this handling can be removed. -- This could've also been solved by not fully rehydrating a package on save by the end user, which will be added as a project setting in a future piece of work, but this approach will solve the edge case when the user does have a large amount of hydrated packages which contain payloads that are already virtualized so it was better to fix that now while we have good test cases for it. -- We still have scaling problems with large number of package being submitted that do have payloads that need to be virtualized, this will be fixed by extending IVirtualizationSystem::Push to also accept batches of payloads in future work. -- OnPrePackageSubmission could be broken up into smaller chunks to make the code easier to follow. This will be done after the batch payload submission work is done. ### VirtualizationSystem - EStorageType has been promoted to enum class. - Added a new enum FPayloadStatus to be used when querying if a payload exists in a backend storage system or not. - Add a new method ::DoPayloadsExist which allows the caller to query if one or more payloads exists in the given backend storage system. ### VirtualizationManager - Implemented ::DoPayloadsExist. First we get the results from each backend in the storage system (which return as true or false from each backend) then total how many backends found the payload in order to set the correct status. ### IVirtualizationBackend - ::DoesPayloadExist which queries the existence of a single payload has been added to the interface. Most backends already implemented this for private use and if so have had their implementation renamed to match this. - Also added ::DoPayloadsExist which takes a batch of FpayloadIdsto query. Some backends can deal with a batch of payload ids much more efficiently than one at a time, although the default implementation does call ::DoesPayloadExist for each requested payload. -- The default implementation prevents every backend from needing to implement the same for loop but does allow backends that can gain from batching to override it. ### VirtualizationSourceControlBackend - This backend does override ::DoPayloadsExist and implements it's own version as it tends to perform very poorly when not operating on larger batches. - In this case ::DoesPayloadExist calls back to ::DoPayloadsExist to check each payload rather than implement as specific version. ### PackageTrailer - The trailer can now be queries to request how many payloads of a given type it contains #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18339847 in //UE5/Release-5.0/... via CL 18339852 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v895-18170469) [CL 18339859 by paul chipchase in ue5-release-engine-test branch]
2021-12-01 11:13:31 -05:00
for (IVirtualizationBackend* Backend : Backends)
{
if (!Backend->DoPayloadsExist(Ids, Results))
{
// If a backend entirely failed we should early out and report the problem
OutStatuses.Reset();
return EQueryResult::Failure_Unknown;
Submitting packages on projects with virtualization enabled is much faster when none of the payloads actually needs to be virtualized. #rb PJ.Kack #rnx #preflight 61a795773c29b3cf13cd8250 ### PackageSubmissionChecks - Under the old model submitting a large number of packages could be very slow as each package would check each payload that it owns and is currently stored locally one at a time. For the source control backend this created quite a large overhead even when all of the payloads were already virtualized. - Now we do a pass over the submitted files to find all valid packages that have package trailers with locally stored payloads, gather the payloads into a single list and then query that in one large batch. - Once we find which payloads are not in permanent storage (note that in the case where a project is using multiple permanent storage solutions, if a payload is missing in one backend it counts as not being in permanent storage) we then attempt to virtualized them. - Only after all of this is done will we create the truncated copy of each package and then append the updated trailer to each one. In theory doing it in this order this might slightly increase the change of submit failures that occur after virtualization that result in a package never being submitted and orphaned payloads being added to permanent storage, but this will always be a risk. - Added an assert to fire if we detect a trailer with some virtualized and some local payloads. This should be a supported feature but needs proper testing first before we can allow it. With out current project settings no project should actually encounter this scenario. - To make the code easier to follow we now early out of the entire check when errors are encountered. - Added logging at various stages in the process to help show the user that something is happening and make problems easier to identify in the future. - Notes -- There is a lot of handling of invalid FPayloads. This is because it is currently possible to add empty payloads to the trailer which is inefficient and wastes space. The trailer will be modified to reject empty payloads in a future update at which point a lot of this handling can be removed. -- This could've also been solved by not fully rehydrating a package on save by the end user, which will be added as a project setting in a future piece of work, but this approach will solve the edge case when the user does have a large amount of hydrated packages which contain payloads that are already virtualized so it was better to fix that now while we have good test cases for it. -- We still have scaling problems with large number of package being submitted that do have payloads that need to be virtualized, this will be fixed by extending IVirtualizationSystem::Push to also accept batches of payloads in future work. -- OnPrePackageSubmission could be broken up into smaller chunks to make the code easier to follow. This will be done after the batch payload submission work is done. ### VirtualizationSystem - EStorageType has been promoted to enum class. - Added a new enum FPayloadStatus to be used when querying if a payload exists in a backend storage system or not. - Add a new method ::DoPayloadsExist which allows the caller to query if one or more payloads exists in the given backend storage system. ### VirtualizationManager - Implemented ::DoPayloadsExist. First we get the results from each backend in the storage system (which return as true or false from each backend) then total how many backends found the payload in order to set the correct status. ### IVirtualizationBackend - ::DoesPayloadExist which queries the existence of a single payload has been added to the interface. Most backends already implemented this for private use and if so have had their implementation renamed to match this. - Also added ::DoPayloadsExist which takes a batch of FpayloadIdsto query. Some backends can deal with a batch of payload ids much more efficiently than one at a time, although the default implementation does call ::DoesPayloadExist for each requested payload. -- The default implementation prevents every backend from needing to implement the same for loop but does allow backends that can gain from batching to override it. ### VirtualizationSourceControlBackend - This backend does override ::DoPayloadsExist and implements it's own version as it tends to perform very poorly when not operating on larger batches. - In this case ::DoesPayloadExist calls back to ::DoPayloadsExist to check each payload rather than implement as specific version. ### PackageTrailer - The trailer can now be queries to request how many payloads of a given type it contains #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18339847 in //UE5/Release-5.0/... via CL 18339852 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v895-18170469) [CL 18339859 by paul chipchase in ue5-release-engine-test branch]
2021-12-01 11:13:31 -05:00
}
for (int32 Index = 0; Index < Ids.Num(); ++Index)
{
if (!Ids[Index].IsZero() && Results[Index])
Submitting packages on projects with virtualization enabled is much faster when none of the payloads actually needs to be virtualized. #rb PJ.Kack #rnx #preflight 61a795773c29b3cf13cd8250 ### PackageSubmissionChecks - Under the old model submitting a large number of packages could be very slow as each package would check each payload that it owns and is currently stored locally one at a time. For the source control backend this created quite a large overhead even when all of the payloads were already virtualized. - Now we do a pass over the submitted files to find all valid packages that have package trailers with locally stored payloads, gather the payloads into a single list and then query that in one large batch. - Once we find which payloads are not in permanent storage (note that in the case where a project is using multiple permanent storage solutions, if a payload is missing in one backend it counts as not being in permanent storage) we then attempt to virtualized them. - Only after all of this is done will we create the truncated copy of each package and then append the updated trailer to each one. In theory doing it in this order this might slightly increase the change of submit failures that occur after virtualization that result in a package never being submitted and orphaned payloads being added to permanent storage, but this will always be a risk. - Added an assert to fire if we detect a trailer with some virtualized and some local payloads. This should be a supported feature but needs proper testing first before we can allow it. With out current project settings no project should actually encounter this scenario. - To make the code easier to follow we now early out of the entire check when errors are encountered. - Added logging at various stages in the process to help show the user that something is happening and make problems easier to identify in the future. - Notes -- There is a lot of handling of invalid FPayloads. This is because it is currently possible to add empty payloads to the trailer which is inefficient and wastes space. The trailer will be modified to reject empty payloads in a future update at which point a lot of this handling can be removed. -- This could've also been solved by not fully rehydrating a package on save by the end user, which will be added as a project setting in a future piece of work, but this approach will solve the edge case when the user does have a large amount of hydrated packages which contain payloads that are already virtualized so it was better to fix that now while we have good test cases for it. -- We still have scaling problems with large number of package being submitted that do have payloads that need to be virtualized, this will be fixed by extending IVirtualizationSystem::Push to also accept batches of payloads in future work. -- OnPrePackageSubmission could be broken up into smaller chunks to make the code easier to follow. This will be done after the batch payload submission work is done. ### VirtualizationSystem - EStorageType has been promoted to enum class. - Added a new enum FPayloadStatus to be used when querying if a payload exists in a backend storage system or not. - Add a new method ::DoPayloadsExist which allows the caller to query if one or more payloads exists in the given backend storage system. ### VirtualizationManager - Implemented ::DoPayloadsExist. First we get the results from each backend in the storage system (which return as true or false from each backend) then total how many backends found the payload in order to set the correct status. ### IVirtualizationBackend - ::DoesPayloadExist which queries the existence of a single payload has been added to the interface. Most backends already implemented this for private use and if so have had their implementation renamed to match this. - Also added ::DoPayloadsExist which takes a batch of FpayloadIdsto query. Some backends can deal with a batch of payload ids much more efficiently than one at a time, although the default implementation does call ::DoesPayloadExist for each requested payload. -- The default implementation prevents every backend from needing to implement the same for loop but does allow backends that can gain from batching to override it. ### VirtualizationSourceControlBackend - This backend does override ::DoPayloadsExist and implements it's own version as it tends to perform very poorly when not operating on larger batches. - In this case ::DoesPayloadExist calls back to ::DoPayloadsExist to check each payload rather than implement as specific version. ### PackageTrailer - The trailer can now be queries to request how many payloads of a given type it contains #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18339847 in //UE5/Release-5.0/... via CL 18339852 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v895-18170469) [CL 18339859 by paul chipchase in ue5-release-engine-test branch]
2021-12-01 11:13:31 -05:00
{
HitCount[Index]++;
}
}
}
}
// Now we total up the hit count for each payload to see if it was found in none, all or some of the backends
for (int32 Index = 0; Index < Ids.Num(); ++Index)
{
if (!Ids[Index].IsZero())
Submitting packages on projects with virtualization enabled is much faster when none of the payloads actually needs to be virtualized. #rb PJ.Kack #rnx #preflight 61a795773c29b3cf13cd8250 ### PackageSubmissionChecks - Under the old model submitting a large number of packages could be very slow as each package would check each payload that it owns and is currently stored locally one at a time. For the source control backend this created quite a large overhead even when all of the payloads were already virtualized. - Now we do a pass over the submitted files to find all valid packages that have package trailers with locally stored payloads, gather the payloads into a single list and then query that in one large batch. - Once we find which payloads are not in permanent storage (note that in the case where a project is using multiple permanent storage solutions, if a payload is missing in one backend it counts as not being in permanent storage) we then attempt to virtualized them. - Only after all of this is done will we create the truncated copy of each package and then append the updated trailer to each one. In theory doing it in this order this might slightly increase the change of submit failures that occur after virtualization that result in a package never being submitted and orphaned payloads being added to permanent storage, but this will always be a risk. - Added an assert to fire if we detect a trailer with some virtualized and some local payloads. This should be a supported feature but needs proper testing first before we can allow it. With out current project settings no project should actually encounter this scenario. - To make the code easier to follow we now early out of the entire check when errors are encountered. - Added logging at various stages in the process to help show the user that something is happening and make problems easier to identify in the future. - Notes -- There is a lot of handling of invalid FPayloads. This is because it is currently possible to add empty payloads to the trailer which is inefficient and wastes space. The trailer will be modified to reject empty payloads in a future update at which point a lot of this handling can be removed. -- This could've also been solved by not fully rehydrating a package on save by the end user, which will be added as a project setting in a future piece of work, but this approach will solve the edge case when the user does have a large amount of hydrated packages which contain payloads that are already virtualized so it was better to fix that now while we have good test cases for it. -- We still have scaling problems with large number of package being submitted that do have payloads that need to be virtualized, this will be fixed by extending IVirtualizationSystem::Push to also accept batches of payloads in future work. -- OnPrePackageSubmission could be broken up into smaller chunks to make the code easier to follow. This will be done after the batch payload submission work is done. ### VirtualizationSystem - EStorageType has been promoted to enum class. - Added a new enum FPayloadStatus to be used when querying if a payload exists in a backend storage system or not. - Add a new method ::DoPayloadsExist which allows the caller to query if one or more payloads exists in the given backend storage system. ### VirtualizationManager - Implemented ::DoPayloadsExist. First we get the results from each backend in the storage system (which return as true or false from each backend) then total how many backends found the payload in order to set the correct status. ### IVirtualizationBackend - ::DoesPayloadExist which queries the existence of a single payload has been added to the interface. Most backends already implemented this for private use and if so have had their implementation renamed to match this. - Also added ::DoPayloadsExist which takes a batch of FpayloadIdsto query. Some backends can deal with a batch of payload ids much more efficiently than one at a time, although the default implementation does call ::DoesPayloadExist for each requested payload. -- The default implementation prevents every backend from needing to implement the same for loop but does allow backends that can gain from batching to override it. ### VirtualizationSourceControlBackend - This backend does override ::DoPayloadsExist and implements it's own version as it tends to perform very poorly when not operating on larger batches. - In this case ::DoesPayloadExist calls back to ::DoPayloadsExist to check each payload rather than implement as specific version. ### PackageTrailer - The trailer can now be queries to request how many payloads of a given type it contains #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18339847 in //UE5/Release-5.0/... via CL 18339852 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v895-18170469) [CL 18339859 by paul chipchase in ue5-release-engine-test branch]
2021-12-01 11:13:31 -05:00
{
if (HitCount[Index] == 0)
{
OutStatuses[Index] = FPayloadStatus::NotFound;
}
else if (HitCount[Index] == Backends.Num())
{
OutStatuses[Index] = FPayloadStatus::FoundAll;
}
else
{
OutStatuses[Index] = FPayloadStatus::FoundPartial;
Submitting packages on projects with virtualization enabled is much faster when none of the payloads actually needs to be virtualized. #rb PJ.Kack #rnx #preflight 61a795773c29b3cf13cd8250 ### PackageSubmissionChecks - Under the old model submitting a large number of packages could be very slow as each package would check each payload that it owns and is currently stored locally one at a time. For the source control backend this created quite a large overhead even when all of the payloads were already virtualized. - Now we do a pass over the submitted files to find all valid packages that have package trailers with locally stored payloads, gather the payloads into a single list and then query that in one large batch. - Once we find which payloads are not in permanent storage (note that in the case where a project is using multiple permanent storage solutions, if a payload is missing in one backend it counts as not being in permanent storage) we then attempt to virtualized them. - Only after all of this is done will we create the truncated copy of each package and then append the updated trailer to each one. In theory doing it in this order this might slightly increase the change of submit failures that occur after virtualization that result in a package never being submitted and orphaned payloads being added to permanent storage, but this will always be a risk. - Added an assert to fire if we detect a trailer with some virtualized and some local payloads. This should be a supported feature but needs proper testing first before we can allow it. With out current project settings no project should actually encounter this scenario. - To make the code easier to follow we now early out of the entire check when errors are encountered. - Added logging at various stages in the process to help show the user that something is happening and make problems easier to identify in the future. - Notes -- There is a lot of handling of invalid FPayloads. This is because it is currently possible to add empty payloads to the trailer which is inefficient and wastes space. The trailer will be modified to reject empty payloads in a future update at which point a lot of this handling can be removed. -- This could've also been solved by not fully rehydrating a package on save by the end user, which will be added as a project setting in a future piece of work, but this approach will solve the edge case when the user does have a large amount of hydrated packages which contain payloads that are already virtualized so it was better to fix that now while we have good test cases for it. -- We still have scaling problems with large number of package being submitted that do have payloads that need to be virtualized, this will be fixed by extending IVirtualizationSystem::Push to also accept batches of payloads in future work. -- OnPrePackageSubmission could be broken up into smaller chunks to make the code easier to follow. This will be done after the batch payload submission work is done. ### VirtualizationSystem - EStorageType has been promoted to enum class. - Added a new enum FPayloadStatus to be used when querying if a payload exists in a backend storage system or not. - Add a new method ::DoPayloadsExist which allows the caller to query if one or more payloads exists in the given backend storage system. ### VirtualizationManager - Implemented ::DoPayloadsExist. First we get the results from each backend in the storage system (which return as true or false from each backend) then total how many backends found the payload in order to set the correct status. ### IVirtualizationBackend - ::DoesPayloadExist which queries the existence of a single payload has been added to the interface. Most backends already implemented this for private use and if so have had their implementation renamed to match this. - Also added ::DoPayloadsExist which takes a batch of FpayloadIdsto query. Some backends can deal with a batch of payload ids much more efficiently than one at a time, although the default implementation does call ::DoesPayloadExist for each requested payload. -- The default implementation prevents every backend from needing to implement the same for loop but does allow backends that can gain from batching to override it. ### VirtualizationSourceControlBackend - This backend does override ::DoPayloadsExist and implements it's own version as it tends to perform very poorly when not operating on larger batches. - In this case ::DoesPayloadExist calls back to ::DoPayloadsExist to check each payload rather than implement as specific version. ### PackageTrailer - The trailer can now be queries to request how many payloads of a given type it contains #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18339847 in //UE5/Release-5.0/... via CL 18339852 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v895-18170469) [CL 18339859 by paul chipchase in ue5-release-engine-test branch]
2021-12-01 11:13:31 -05:00
}
}
}
return EQueryResult::Success;
Submitting packages on projects with virtualization enabled is much faster when none of the payloads actually needs to be virtualized. #rb PJ.Kack #rnx #preflight 61a795773c29b3cf13cd8250 ### PackageSubmissionChecks - Under the old model submitting a large number of packages could be very slow as each package would check each payload that it owns and is currently stored locally one at a time. For the source control backend this created quite a large overhead even when all of the payloads were already virtualized. - Now we do a pass over the submitted files to find all valid packages that have package trailers with locally stored payloads, gather the payloads into a single list and then query that in one large batch. - Once we find which payloads are not in permanent storage (note that in the case where a project is using multiple permanent storage solutions, if a payload is missing in one backend it counts as not being in permanent storage) we then attempt to virtualized them. - Only after all of this is done will we create the truncated copy of each package and then append the updated trailer to each one. In theory doing it in this order this might slightly increase the change of submit failures that occur after virtualization that result in a package never being submitted and orphaned payloads being added to permanent storage, but this will always be a risk. - Added an assert to fire if we detect a trailer with some virtualized and some local payloads. This should be a supported feature but needs proper testing first before we can allow it. With out current project settings no project should actually encounter this scenario. - To make the code easier to follow we now early out of the entire check when errors are encountered. - Added logging at various stages in the process to help show the user that something is happening and make problems easier to identify in the future. - Notes -- There is a lot of handling of invalid FPayloads. This is because it is currently possible to add empty payloads to the trailer which is inefficient and wastes space. The trailer will be modified to reject empty payloads in a future update at which point a lot of this handling can be removed. -- This could've also been solved by not fully rehydrating a package on save by the end user, which will be added as a project setting in a future piece of work, but this approach will solve the edge case when the user does have a large amount of hydrated packages which contain payloads that are already virtualized so it was better to fix that now while we have good test cases for it. -- We still have scaling problems with large number of package being submitted that do have payloads that need to be virtualized, this will be fixed by extending IVirtualizationSystem::Push to also accept batches of payloads in future work. -- OnPrePackageSubmission could be broken up into smaller chunks to make the code easier to follow. This will be done after the batch payload submission work is done. ### VirtualizationSystem - EStorageType has been promoted to enum class. - Added a new enum FPayloadStatus to be used when querying if a payload exists in a backend storage system or not. - Add a new method ::DoPayloadsExist which allows the caller to query if one or more payloads exists in the given backend storage system. ### VirtualizationManager - Implemented ::DoPayloadsExist. First we get the results from each backend in the storage system (which return as true or false from each backend) then total how many backends found the payload in order to set the correct status. ### IVirtualizationBackend - ::DoesPayloadExist which queries the existence of a single payload has been added to the interface. Most backends already implemented this for private use and if so have had their implementation renamed to match this. - Also added ::DoPayloadsExist which takes a batch of FpayloadIdsto query. Some backends can deal with a batch of payload ids much more efficiently than one at a time, although the default implementation does call ::DoesPayloadExist for each requested payload. -- The default implementation prevents every backend from needing to implement the same for loop but does allow backends that can gain from batching to override it. ### VirtualizationSourceControlBackend - This backend does override ::DoPayloadsExist and implements it's own version as it tends to perform very poorly when not operating on larger batches. - In this case ::DoesPayloadExist calls back to ::DoPayloadsExist to check each payload rather than implement as specific version. ### PackageTrailer - The trailer can now be queries to request how many payloads of a given type it contains #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18339847 in //UE5/Release-5.0/... via CL 18339852 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v895-18170469) [CL 18339859 by paul chipchase in ue5-release-engine-test branch]
2021-12-01 11:13:31 -05:00
}
bool FVirtualizationManager::TryVirtualizePackages(const TArray<FString>& FilesToVirtualize, TArray<FText>& OutDescriptionTags, TArray<FText>& OutErrors)
{
OutDescriptionTags.Reset();
OutErrors.Reset();
UE::Virtualization::VirtualizePackages(FilesToVirtualize, OutDescriptionTags, OutErrors);
return OutErrors.IsEmpty();
}
FPayloadActivityInfo FVirtualizationManager::GetAccumualtedPayloadActivityInfo() const
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
{
FPayloadActivityInfo Info;
#if ENABLE_COOK_STATS
for (const auto& Iterator : Profiling::CacheStats)
{
Info.Cache.PayloadCount += Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Counter);
Info.Cache.TotalBytes += Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Bytes);
Info.Cache.CyclesSpent += Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Cycles);
}
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
for (const auto& Iterator : Profiling::PushStats)
{
Info.Push.PayloadCount += Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Counter);
Info.Push.TotalBytes += Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Bytes);
Info.Push.CyclesSpent += Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Cycles);
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
}
for (const auto& Iterator : Profiling::PullStats)
{
Info.Pull.PayloadCount += Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Counter);
Info.Pull.TotalBytes += Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Bytes);
Info.Pull.CyclesSpent += Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Cycles);
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
}
#endif // ENABLE_COOK_STATS
return Info;
}
void FVirtualizationManager::GetPayloadActivityInfo( GetPayloadActivityInfoFuncRef GetPayloadFunc ) const
{
FPayloadActivityInfo Info;
#if ENABLE_COOK_STATS
for (const auto& Backend : AllBackends)
{
const FCookStats::CallStats& CacheStats = Profiling::GetCacheStats(*Backend);
Info.Cache.PayloadCount = CacheStats.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Counter);
Info.Cache.TotalBytes = CacheStats.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Bytes);
Info.Cache.CyclesSpent = CacheStats.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Cycles);
const FCookStats::CallStats& PushStats = Profiling::GetPushStats(*Backend);
Info.Push.PayloadCount = PushStats.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Counter);
Info.Push.TotalBytes = PushStats.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Bytes);
Info.Push.CyclesSpent = PushStats.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Cycles);
const FCookStats::CallStats& PullStats = Profiling::GetPullStats(*Backend);
Info.Pull.PayloadCount = PullStats.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Counter);
Info.Pull.TotalBytes = PullStats.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Bytes);
Info.Pull.CyclesSpent = PullStats.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Cycles);
GetPayloadFunc(Backend->GetDebugName(), Backend->GetConfigName(), Info);
}
#endif // ENABLE_COOK_STATS
}
void FVirtualizationManager::ApplySettingsFromConfigFiles(const FConfigFile& ConfigFile)
{
UE_LOG(LogVirtualization, Display, TEXT("Loading virtualization manager settings from config files..."));
bool bEnablePayloadPushingFromIni = false;
if (ConfigFile.GetBool(TEXT("Core.ContentVirtualization"), TEXT("EnablePushToBackend"), bEnablePayloadPushingFromIni))
{
bEnablePayloadPushing = bEnablePayloadPushingFromIni;
UE_LOG(LogVirtualization, Display, TEXT("\tEnablePushToBackend : %s"), bEnablePayloadPushing ? TEXT("true") : TEXT("false") );
}
else
{
UE_LOG(LogVirtualization, Error, TEXT("Failed to load [Core.ContentVirtualization].EnablePushToBackend from config file!"));
}
bool bEnableCacheAfterPullFromIni = false;
if (ConfigFile.GetBool(TEXT("Core.ContentVirtualization"), TEXT("EnableCacheAfterPull"), bEnableCacheAfterPullFromIni))
{
bEnableCacheAfterPull = bEnableCacheAfterPullFromIni;
UE_LOG(LogVirtualization, Display, TEXT("\tCachePulledPayloads : %s"), bEnableCacheAfterPull ? TEXT("true") : TEXT("false"));
}
else
{
UE_LOG(LogVirtualization, Error, TEXT("Failed to load [Core.ContentVirtualization].EnableCacheAfterPull from config file!"));
}
int64 MinPayloadLengthFromIni = 0;
if (ConfigFile.GetInt64(TEXT("Core.ContentVirtualization"), TEXT("MinPayloadLength"), MinPayloadLengthFromIni))
{
MinPayloadLength = MinPayloadLengthFromIni;
UE_LOG(LogVirtualization, Display, TEXT("\tMinPayloadLength : %" INT64_FMT), MinPayloadLength );
}
else
{
Allow the virtualization of assets to be opt in, as well as opt out. This would allow a project to selectively turn on virtualization for specific locations or plugins rather than for the whole project by default. #rb PJ.Kack #jira UE-133473 #preflight 620bf6ae483ff0ae5ec22257 ### VirtualizationManager - Added EPackageFilterMode that can be set via [Core.ContentVirtualization] in the config file to control the default virtualization behavior. -- When set to EPackageFilterMode::OptOut(the default) all package paths will virtualize unless excluded by a pattern in UVirtualizationFilterSettings::ExcludePackagePaths. -- When set to EPackageFilterMode::OptIn then no package path will virtualize unless included by a pattern in UVirtualizationFilterSettings::IncludePackagePaths. - Added a TRACE_CPUPROFILER_EVENT_SCOPE to the constructor and ::MountBackends to better track the set up time costs. - Change use of FConfigCacheIni::LoadLocalIniFile to use GConfig, there is no need to load our own. - Improved verbose logging to show when a payload is rejected via filtering. - We now early out if all payloads being requested in a push are rejected during validation. - Renamed the FString overload for ::ShouldVirtualizePackage to ::ShouldVirtualize to make the difference clearer. - Added support for UVirtualizationFilterSettings::ExcludePackagePaths when filtering ### UVirtualizationFilterSettings - Now has a new FString array ExcludePackagePaths, which contains the paths/patterns used to force packages to be virtualized when filtering. [CL 19010992 by paul chipchase in ue5-main branch]
2022-02-16 01:27:09 -05:00
UE_LOG(LogVirtualization, Error, TEXT("Failed to load [Core.ContentVirtualization].MinPayloadLength from config file!"));
}
FString BackendGraphNameFromIni;
if (ConfigFile.GetString(TEXT("Core.ContentVirtualization"), TEXT("BackendGraph"), BackendGraphNameFromIni))
{
BackendGraphName = BackendGraphNameFromIni;
UE_LOG(LogVirtualization, Display, TEXT("\tBackendGraphName : %s"), *BackendGraphName );
}
else
{
Allow the virtualization of assets to be opt in, as well as opt out. This would allow a project to selectively turn on virtualization for specific locations or plugins rather than for the whole project by default. #rb PJ.Kack #jira UE-133473 #preflight 620bf6ae483ff0ae5ec22257 ### VirtualizationManager - Added EPackageFilterMode that can be set via [Core.ContentVirtualization] in the config file to control the default virtualization behavior. -- When set to EPackageFilterMode::OptOut(the default) all package paths will virtualize unless excluded by a pattern in UVirtualizationFilterSettings::ExcludePackagePaths. -- When set to EPackageFilterMode::OptIn then no package path will virtualize unless included by a pattern in UVirtualizationFilterSettings::IncludePackagePaths. - Added a TRACE_CPUPROFILER_EVENT_SCOPE to the constructor and ::MountBackends to better track the set up time costs. - Change use of FConfigCacheIni::LoadLocalIniFile to use GConfig, there is no need to load our own. - Improved verbose logging to show when a payload is rejected via filtering. - We now early out if all payloads being requested in a push are rejected during validation. - Renamed the FString overload for ::ShouldVirtualizePackage to ::ShouldVirtualize to make the difference clearer. - Added support for UVirtualizationFilterSettings::ExcludePackagePaths when filtering ### UVirtualizationFilterSettings - Now has a new FString array ExcludePackagePaths, which contains the paths/patterns used to force packages to be virtualized when filtering. [CL 19010992 by paul chipchase in ue5-main branch]
2022-02-16 01:27:09 -05:00
UE_LOG(LogVirtualization, Error, TEXT("Failed to load [Core.ContentVirtualization].BackendGraph from config file!"));
}
FString FilterModeFromIni;
if (ConfigFile.GetString(TEXT("Core.ContentVirtualization"), TEXT("FilterMode"), FilterModeFromIni))
Allow the virtualization of assets to be opt in, as well as opt out. This would allow a project to selectively turn on virtualization for specific locations or plugins rather than for the whole project by default. #rb PJ.Kack #jira UE-133473 #preflight 620bf6ae483ff0ae5ec22257 ### VirtualizationManager - Added EPackageFilterMode that can be set via [Core.ContentVirtualization] in the config file to control the default virtualization behavior. -- When set to EPackageFilterMode::OptOut(the default) all package paths will virtualize unless excluded by a pattern in UVirtualizationFilterSettings::ExcludePackagePaths. -- When set to EPackageFilterMode::OptIn then no package path will virtualize unless included by a pattern in UVirtualizationFilterSettings::IncludePackagePaths. - Added a TRACE_CPUPROFILER_EVENT_SCOPE to the constructor and ::MountBackends to better track the set up time costs. - Change use of FConfigCacheIni::LoadLocalIniFile to use GConfig, there is no need to load our own. - Improved verbose logging to show when a payload is rejected via filtering. - We now early out if all payloads being requested in a push are rejected during validation. - Renamed the FString overload for ::ShouldVirtualizePackage to ::ShouldVirtualize to make the difference clearer. - Added support for UVirtualizationFilterSettings::ExcludePackagePaths when filtering ### UVirtualizationFilterSettings - Now has a new FString array ExcludePackagePaths, which contains the paths/patterns used to force packages to be virtualized when filtering. [CL 19010992 by paul chipchase in ue5-main branch]
2022-02-16 01:27:09 -05:00
{
if(LexTryParseString(FilteringMode, FilterModeFromIni))
{
UE_LOG(LogVirtualization, Display, TEXT("\tFilterMode : %s"), *FilterModeFromIni);
Allow the virtualization of assets to be opt in, as well as opt out. This would allow a project to selectively turn on virtualization for specific locations or plugins rather than for the whole project by default. #rb PJ.Kack #jira UE-133473 #preflight 620bf6ae483ff0ae5ec22257 ### VirtualizationManager - Added EPackageFilterMode that can be set via [Core.ContentVirtualization] in the config file to control the default virtualization behavior. -- When set to EPackageFilterMode::OptOut(the default) all package paths will virtualize unless excluded by a pattern in UVirtualizationFilterSettings::ExcludePackagePaths. -- When set to EPackageFilterMode::OptIn then no package path will virtualize unless included by a pattern in UVirtualizationFilterSettings::IncludePackagePaths. - Added a TRACE_CPUPROFILER_EVENT_SCOPE to the constructor and ::MountBackends to better track the set up time costs. - Change use of FConfigCacheIni::LoadLocalIniFile to use GConfig, there is no need to load our own. - Improved verbose logging to show when a payload is rejected via filtering. - We now early out if all payloads being requested in a push are rejected during validation. - Renamed the FString overload for ::ShouldVirtualizePackage to ::ShouldVirtualize to make the difference clearer. - Added support for UVirtualizationFilterSettings::ExcludePackagePaths when filtering ### UVirtualizationFilterSettings - Now has a new FString array ExcludePackagePaths, which contains the paths/patterns used to force packages to be virtualized when filtering. [CL 19010992 by paul chipchase in ue5-main branch]
2022-02-16 01:27:09 -05:00
}
else
{
UE_LOG(LogVirtualization, Error, TEXT("[Core.ContentVirtualization].FilterMode was an invalid value! Allowed: 'OptIn'|'OptOut' Found '%s'"), *FilterModeFromIni);
}
}
else
{
UE_LOG(LogVirtualization, Error, TEXT("Failed to load [Core.ContentVirtualization]FilterMode from config file!"));
}
bool bFilterEngineContentFromIni = true;
if (ConfigFile.GetBool(TEXT("Core.ContentVirtualization"), TEXT("FilterEngineContent"), bFilterEngineContentFromIni))
{
bFilterEngineContent = bFilterEngineContentFromIni;
UE_LOG(LogVirtualization, Display, TEXT("\tFilterEngineContent : %s"), bFilterEngineContent ? TEXT("true") : TEXT("false"));
}
else
{
UE_LOG(LogVirtualization, Error, TEXT("Failed to load [Core.ContentVirtualization].FilterEngineContent from config file!"));
}
bool bFilterEnginePluginContentFromIni = true;
if (ConfigFile.GetBool(TEXT("Core.ContentVirtualization"), TEXT("FilterEnginePluginContent"), bFilterEnginePluginContentFromIni))
{
bFilterEnginePluginContent = bFilterEnginePluginContentFromIni;
UE_LOG(LogVirtualization, Display, TEXT("\tFilterEnginePluginContent : %s"), bFilterEnginePluginContent ? TEXT("true") : TEXT("false"));
}
else
{
UE_LOG(LogVirtualization, Error, TEXT("Failed to load [Core.ContentVirtualization].FilterEnginePluginContent from config file!"));
It is now possible to disable virtualization for all payloads owned by a specific asset type by adding the name of the asset to [Core.ContentVirtualization]DisabledAsset string array in the engine ini file. #rb Per.Larsson #rnx #jira UE-151377 #preflight 628364050039ea57a52d6989 ### Virtualization - [Core.ContentVirtualization] in the engine ini file now supports an array called 'DisabledAsset' which can be used to name asset types that should not virtualize their payloads. -- By default (in BaseEngine.ini) we have disabled the StaticMesh asset as we know it will crash if a payload is missing and the SoundWave asset as it still is pending testing. - This new way to disable virtualization is data driven. The older hard coded method has not been removed but will likely be reworked in a future submit. - Now when an editor bulkdata is adding it's payload to the package trailer builder during package save it will poll the virtualization system with a call to the new method ::IsDisabledForObject by passing in it's owner. -- If the owner is valid and was present in the 'DisabledAsset' array then the method will return true and the EPayloadFlags::DisableVirtualization flag will be applied. ### Package Trailer - The pre-existing functionality of enum EPayloadFilter has been moved to a new enum EPayloadStorageType as will only filter payloads based on their storage type. - EPayloadFilter has been modified to filter payloads based on functionality although at the moment the only thing it can filter for is to return payloads that can be virtualized, it is left for future expansion. - EPayloadFlags has been reduced to a uint16 with the remaining 2bytes being turned into a new member EPayloadFilterReason. - This new member allows us to record the exact reason why a payload is excluded from virtualization. If it is zero then the payload can virtualize, otherwise it will contain one or more reasons as to why it is being excluded. For this reason the enum is a bitfield. - Added overloads of ::GetPayloads and ::GetNumPayloads that take EPayloadFilter rather than a EPayloadStorageType - Added wrappers around all AccessMode types for FLookupTableEntry. - FPackageTrailerBuilder has been extended to take a EPayloadFilterReason so that the caller can already provide a reason why the payload cannot be virtualized. -- As a future peace of work this will probably be changed and we will ask the caller to pass in the owner UObject pointer instead and then we will process the filtering when building the package trailer to a) keep all of the filtering code in one place b) keep the filtering consistent ### PackageSubmissionChecks - The virtualization process in will now request the payloads that can be virtualized from the package trailer, which respects the new payload flag, rather than requesting all locally stored payloads. ### UObjects - There is no need for the SoundWave or MeshDescription classes to opt out of virtualization on construction. This will be done when the package is saved and is now data driven rather than being hardcoded. ### DumpPackagePayloadInfo - The command has been updated to also display the filter reasons applied to each payload [CL 20240971 by paul chipchase in ue5-main branch]
2022-05-17 07:54:28 -04:00
}
TArray<FString> DisabledAssetTypesFromIni;
if (ConfigFile.GetArray(TEXT("Core.ContentVirtualization"), TEXT("DisabledAsset"), DisabledAssetTypesFromIni) > 0)
{
UE_LOG(LogVirtualization, Display, TEXT("\tVirtualization is disabled for payloads of the following assets:"));
DisabledAssetTypes.Reserve(DisabledAssetTypesFromIni.Num());
for(const FString& AssetType : DisabledAssetTypesFromIni)
{
UE_LOG(LogVirtualization, Display, TEXT("\t\t%s"), *AssetType);
DisabledAssetTypes.Add(FName(AssetType));
}
}
}
void FVirtualizationManager::ApplyDebugSettingsFromFromCmdline()
{
if (FParse::Param(FCommandLine::Get(), TEXT("VA-SingleThreaded")))
{
DebugValues.bSingleThreaded = true;
UE_LOG(LogVirtualization, Warning, TEXT("Cmdline has set the virtualization system to run single threaded"));
}
if (FParse::Param(FCommandLine::Get(), TEXT("VA-ValidatePushes")))
{
DebugValues.bValidateAfterPush = true;
UE_LOG(LogVirtualization, Warning, TEXT("Cmdline has set the virtualization system to pull each payload after pushing to either local or persistent storage"));
}
FString CmdlineGraphName;
if (FParse::Value(FCommandLine::Get(), TEXT("-VA-BackendGraph="), CmdlineGraphName))
{
UE_LOG(LogVirtualization, Display, TEXT("Backend graph overriden from the cmdline: '%s'"), *CmdlineGraphName);
BackendGraphName = CmdlineGraphName;
}
FString MissOptions;
if (FParse::Value(FCommandLine::Get(), TEXT("-VA-MissBackends="), MissOptions))
{
MissOptions.ParseIntoArray(DebugValues.MissBackends, TEXT("+"), true);
UE_LOG(LogVirtualization, Warning, TEXT("Cmdline has disabled payload pulling for the following backends:"));
for (const FString& Backend : DebugValues.MissBackends)
{
UE_LOG(LogVirtualization, Warning, TEXT("\t%s"), *Backend);
}
}
DebugValues.MissChance = 0.0f;
if (FParse::Value(FCommandLine::Get(), TEXT("-VA-MissChance="), DebugValues.MissChance))
{
DebugValues.MissChance = FMath::Clamp(DebugValues.MissChance, 0.0f, 100.0f);
UE_LOG(LogVirtualization, Warning, TEXT("Cmdline has set a %.1f%% chance of a payload pull failing"), DebugValues.MissChance);
}
}
void FVirtualizationManager::RegisterConsoleCommands()
{
DebugValues.ConsoleObjects.Add(IConsoleManager::Get().RegisterConsoleCommand(
TEXT("VA.MissBackends"),
TEXT("A debug commnad which can be used to disable payload pulling on one or more backends"),
FConsoleCommandWithArgsAndOutputDeviceDelegate::CreateRaw(this, &FVirtualizationManager::OnUpdateDebugMissBackendsFromConsole)
));
DebugValues.ConsoleObjects.Add(IConsoleManager::Get().RegisterConsoleCommand(
TEXT("VA.MissChance"),
TEXT("A debug command which can be used to set the chance that a payload pull will fail"),
FConsoleCommandWithArgsAndOutputDeviceDelegate::CreateRaw(this, &FVirtualizationManager::OnUpdateDebugMissChanceFromConsole)
));
DebugValues.ConsoleObjects.Add(IConsoleManager::Get().RegisterConsoleCommand(
TEXT("VA.MissCount"),
TEXT("A debug command which can be used to cause the next X number of payload pulls to fail"),
FConsoleCommandWithArgsAndOutputDeviceDelegate::CreateRaw(this, &FVirtualizationManager::OnUpdateDebugMissCountFromConsole)
));
DebugValues.ConsoleObjects.Add(IConsoleManager::Get().RegisterConsoleVariableRef(
TEXT("VA.SingleThreaded"),
DebugValues.bSingleThreaded,
TEXT("When set the asset virtualization system will only access backends in a single threaded manner")
));
DebugValues.ConsoleObjects.Add(IConsoleManager::Get().RegisterConsoleVariableRef(
TEXT("VA.ValidatePushes"),
DebugValues.bValidateAfterPush,
TEXT("When set the asset virtualization system will pull each payload after pushing to either local or persistent storage")
));
}
void FVirtualizationManager::OnUpdateDebugMissBackendsFromConsole(const TArray<FString>& Args, FOutputDevice& OutputDevice)
{
if (Args.IsEmpty())
{
OutputDevice.Log(TEXT("VA.MissBackends command help"));
OutputDevice.Log(TEXT("This command allows you to disable the pulling of payloads by specific backends"));
OutputDevice.Log(TEXT(""));
OutputDevice.Log(TEXT("Commands:"));
OutputDevice.Log(TEXT("VA.MissBackends reset - Empties the list of backends, everything will function normally"));
OutputDevice.Log(TEXT("VA.MissBackends list - Prints the list of backends affected"));
OutputDevice.Log(TEXT("VA.MissBackends set Name0 Name1 - List each backend that you want to fail to pull payloads"));
OutputDevice.Log(TEXT("VA.MissBackends set All - All backends will fail to pull payloads"));
OutputDevice.Log(TEXT(""));
OutputDevice.Log(TEXT("Valid backend names:"));
for (const TUniquePtr<IVirtualizationBackend>& Backend : AllBackends)
{
OutputDevice.Logf(TEXT("\t%s"), *Backend->GetConfigName());
}
}
else if (Args.Num() == 1)
{
if (Args[0] == TEXT("reset"))
{
DebugValues.MissBackends.Empty();
UpdateBackendDebugState();
}
else if (Args[0] == TEXT("list"))
{
if (!DebugValues.MissBackends.IsEmpty())
{
OutputDevice.Log(TEXT("Disabled backends:"));
for (const FString& Backend : DebugValues.MissBackends)
{
OutputDevice.Logf(TEXT("\t%s"), *Backend);
}
}
else
{
OutputDevice.Log(TEXT("No backends are disabled"));
}
}
else
{
OutputDevice.Log(ELogVerbosity::Error, TEXT("Invalid args for the VA.MissBackends command!"));
}
}
else if (Args[0] == TEXT("set"))
{
DebugValues.MissBackends.Empty(Args.Num() - 1);
for (int32 Index = 1; Index < Args.Num(); ++Index)
{
DebugValues.MissBackends.Add(Args[Index]);
}
UpdateBackendDebugState();
}
else
{
OutputDevice.Log(ELogVerbosity::Error, TEXT("Invalid args for the VA.MissBackends command!"));
}
}
void FVirtualizationManager::OnUpdateDebugMissChanceFromConsole(const TArray<FString>& Args, FOutputDevice& OutputDevice)
{
if (Args.IsEmpty())
{
OutputDevice.Log(TEXT("VA.MissChance command help"));
OutputDevice.Log(TEXT("This command allows you to set the chance (in percent) that a payload pull request will just fail"));
OutputDevice.Log(TEXT(""));
OutputDevice.Log(TEXT("Commands:"));
OutputDevice.Log(TEXT("VA.MissChance show - prints the current miss percent chance"));
OutputDevice.Log(TEXT("VA.MissChance set Num - Sets the miss percent chance to the given value"));
}
else if (Args.Num() == 1 && Args[0] == TEXT("show"))
{
OutputDevice.Logf(TEXT("Current debug miss chance: %.1f%%"), DebugValues.MissChance);
}
else if (Args.Num() == 2 && Args[0] == TEXT("set"))
{
if (::LexTryParseString(DebugValues.MissChance, *Args[1]))
{
DebugValues.MissChance = FMath::Clamp(DebugValues.MissChance, 0.0f, 100.0f);
OutputDevice.Logf(TEXT("Current debug miss chance set to %.1f%%"), DebugValues.MissChance);
}
else
{
DebugValues.MissChance = 0.0f;
OutputDevice.Log(ELogVerbosity::Error, TEXT("Invalid value, current debug miss chance reset to 0.0%"));
}
}
else
{
OutputDevice.Log(ELogVerbosity::Error, TEXT("Invalid args for the VA.MissChance command!"));
}
}
void FVirtualizationManager::OnUpdateDebugMissCountFromConsole(const TArray<FString>& Args, FOutputDevice& OutputDevice)
{
if (Args.IsEmpty())
{
OutputDevice.Log(TEXT("VA.MissCount command help"));
OutputDevice.Log(TEXT("This command allows you to set the next X number of payload pulls to fail"));
OutputDevice.Log(TEXT(""));
OutputDevice.Log(TEXT("Commands:"));
OutputDevice.Log(TEXT("VA.MissCount show - prints the current number of future payload pulls that will fail"));
OutputDevice.Log(TEXT("VA.MissChance set Num - Sets the number of future payload pulls to fail"));
}
else if (Args.Num() == 1 && Args[0] == TEXT("show"))
{
// DebugMissCount could end up negative if many threads are pulling at once, so clamp to 0 as the min value
const int32 Value = FMath::Max(DebugValues.MissCount.load(std::memory_order_relaxed), 0);
OutputDevice.Logf(TEXT("The next '%d' payload pulls will fail"), Value);
}
else if (Args.Num() == 2 && Args[0] == TEXT("set"))
{
int32 ValueToSet = 0;
if (::LexTryParseString(ValueToSet, *Args[1]))
{
DebugValues.MissCount.store(ValueToSet, std::memory_order_relaxed);
OutputDevice.Logf(TEXT("The next '%d' payload pulls have been set to fail"), ValueToSet);
}
else
{
DebugValues.MissCount.store(0, std::memory_order_relaxed);
OutputDevice.Log(ELogVerbosity::Error, TEXT("Invalid value, the number of future payload pulls to fail has been set to zero"));
}
}
else
{
OutputDevice.Log(ELogVerbosity::Error, TEXT("Invalid args for the VA.MissCount command!"));
}
}
void FVirtualizationManager::UpdateBackendDebugState()
{
for (TUniquePtr<IVirtualizationBackend>& Backend : AllBackends)
{
const bool bDisable = ShouldDebugDisablePulling(Backend->GetConfigName());
Backend->SetOperationDebugState(IVirtualizationBackend::EOperations::Pull, bDisable);
}
}
bool FVirtualizationManager::ShouldDebugDisablePulling(FStringView BackendConfigName) const
{
if (DebugValues.MissBackends.IsEmpty())
{
return false;
}
if (DebugValues.MissBackends[0] == TEXT("All"))
{
return true;
}
for (const FString& Name : DebugValues.MissBackends)
{
if (Name == BackendConfigName)
{
return true;
}
}
return false;
}
bool FVirtualizationManager::ShouldDebugFailPulling()
{
// We don't want to decrement on every function call to avoid DebugMissCount
// underflowing, so we only try to decrement if the count is positive.
// It doesn't really matter if the value ends up a little bit negative.
if (DebugValues.MissCount.load(std::memory_order_relaxed) > 0)
{
if (DebugValues.MissCount.fetch_sub(1, std::memory_order_relaxed) > 0)
{
return true;
}
}
if (DebugValues.MissChance == 0.0f)
{
return false;
}
else
{
// Could consider adding a lock here, although FRandomStream
// is thread safe, many threads hitting it could cause a few
// threads to get the same results.
// Since this is a debug function and the percent is only a
// rough guide, adding a lock is considered overkill. This
// should only be done if in the future we decide that we want
// more accuracy.
static FRandomStream RandomStream(NAME_None);
const float RandValue = RandomStream.FRand() * 100.0f;
return RandValue <= DebugValues.MissChance;
}
}
void FVirtualizationManager::MountBackends(const FConfigFile& ConfigFile)
{
Allow the virtualization of assets to be opt in, as well as opt out. This would allow a project to selectively turn on virtualization for specific locations or plugins rather than for the whole project by default. #rb PJ.Kack #jira UE-133473 #preflight 620bf6ae483ff0ae5ec22257 ### VirtualizationManager - Added EPackageFilterMode that can be set via [Core.ContentVirtualization] in the config file to control the default virtualization behavior. -- When set to EPackageFilterMode::OptOut(the default) all package paths will virtualize unless excluded by a pattern in UVirtualizationFilterSettings::ExcludePackagePaths. -- When set to EPackageFilterMode::OptIn then no package path will virtualize unless included by a pattern in UVirtualizationFilterSettings::IncludePackagePaths. - Added a TRACE_CPUPROFILER_EVENT_SCOPE to the constructor and ::MountBackends to better track the set up time costs. - Change use of FConfigCacheIni::LoadLocalIniFile to use GConfig, there is no need to load our own. - Improved verbose logging to show when a payload is rejected via filtering. - We now early out if all payloads being requested in a push are rejected during validation. - Renamed the FString overload for ::ShouldVirtualizePackage to ::ShouldVirtualize to make the difference clearer. - Added support for UVirtualizationFilterSettings::ExcludePackagePaths when filtering ### UVirtualizationFilterSettings - Now has a new FString array ExcludePackagePaths, which contains the paths/patterns used to force packages to be virtualized when filtering. [CL 19010992 by paul chipchase in ue5-main branch]
2022-02-16 01:27:09 -05:00
TRACE_CPUPROFILER_EVENT_SCOPE(FVirtualizationManager::MountBackends);
const FRegistedFactories FactoryLookupTable = FindBackendFactories();
UE_LOG(LogVirtualization, Verbose, TEXT("Found %d backend factories"), FactoryLookupTable.Num());
const TCHAR* GraphName = *BackendGraphName;
if(!ConfigFile.DoesSectionExist(GraphName))
{
UE_LOG(LogVirtualization, Fatal, TEXT("Unable to find the backend graph: '%s' [ini=%s]."), GraphName, *GEngineIni);
}
UE_LOG(LogVirtualization, Display, TEXT("Mounting virtualization backend graph: '%s'"), GraphName);
// It is important to parse the local storage hierarchy first so those backends will show up before the
// persistent storage backends in 'PullEnabledBackends'.
ParseHierarchy(ConfigFile, GraphName, TEXT("LocalStorageHierarchy"), FactoryLookupTable, LocalCachableBackends);
ParseHierarchy(ConfigFile, GraphName, TEXT("PersistentStorageHierarchy"), FactoryLookupTable, PersistentStorageBackends);
// Apply and disabled backends from the command line
UpdateBackendDebugState();
}
void FVirtualizationManager::ParseHierarchy(const FConfigFile& ConfigFile, const TCHAR* GraphName, const TCHAR* HierarchyKey, const FRegistedFactories& FactoryLookupTable, FBackendArray& PushArray)
{
FString HierarchyData;
if (!ConfigFile.GetValue(GraphName, HierarchyKey, HierarchyData))
{
UE_LOG(LogVirtualization, Fatal, TEXT("Unable to find the '%s' entry for the content virtualization backend graph '%s' [ini=%s]."), HierarchyKey, GraphName, *GEngineIni);
}
if (HierarchyData.IsEmpty())
{
UE_LOG(LogVirtualization, Fatal, TEXT("The '%s' entry for backend graph '%s' is empty [ini=%s]."), HierarchyKey, GraphName, *GEngineIni);
}
const TArray<FString> Entries = ParseEntries(HierarchyData);
UE_LOG(LogVirtualization, Display, TEXT("'%s' has %d backend(s)"), HierarchyKey, Entries.Num());
for (const FString& Entry : Entries)
{
CreateBackend(ConfigFile, GraphName, Entry, FactoryLookupTable, PushArray);
}
}
bool FVirtualizationManager::CreateBackend(const FConfigFile& ConfigFile, const TCHAR* GraphName, const FString& ConfigEntryName, const FRegistedFactories& FactoryLookupTable, FBackendArray& PushArray)
{
// All failures in this method are considered fatal, however it still returns true/false in case we decide
// to be more forgiving in the future.
UE_LOG(LogVirtualization, Display, TEXT("Mounting backend entry '%s'"), *ConfigEntryName);
FString BackendData;
if (!ConfigFile.GetValue(GraphName, *ConfigEntryName, BackendData))
{
UE_LOG(LogVirtualization, Fatal, TEXT("Unable to find the entry '%s' in the content virtualization backend graph '%s' [ini=%s]."), *ConfigEntryName, GraphName, *GEngineIni);
return false;
}
FString BackendType;
if (FParse::Value(*BackendData, TEXT("Type="), BackendType) && !BackendType.IsEmpty())
{
// Put the rest of the ini file entry into a string to pass to the backend.
FString Cmdine = BackendData.RightChop(BackendData.Find(BackendType) + BackendType.Len());
Cmdine.RemoveFromEnd(TEXT(")"));
UE::Virtualization::IVirtualizationBackendFactory* const* FactoryPtr = FactoryLookupTable.Find(FName(BackendType));
if (FactoryPtr != nullptr && *FactoryPtr != nullptr)
{
IVirtualizationBackendFactory* Factory = *FactoryPtr;
TUniquePtr<IVirtualizationBackend> Backend = Factory->CreateInstance(ProjectName, ConfigEntryName);
if (Backend == nullptr)
{
UE_LOG(LogVirtualization, Fatal, TEXT("IVirtualizationBackendFactory '%s' failed to create an instance!"), *Factory->GetName().ToString());
return false;
}
if (Backend->Initialize(Cmdine))
{
AddBackend(MoveTemp(Backend), PushArray);
}
else
{
UE_LOG(LogVirtualization, Fatal, TEXT("Backend '%s' reported errors when initializing"), *ConfigEntryName);
return false;
}
}
else
{
UE_LOG(LogVirtualization, Fatal, TEXT("No backend factory found that can create the type '%s'"), *BackendType);
return false;
}
}
else
{
UE_LOG(LogVirtualization, Fatal, TEXT("No 'Type=' entry found for '%s' in the config file"), *ConfigEntryName);
return false;
}
return true;
}
void FVirtualizationManager::AddBackend(TUniquePtr<IVirtualizationBackend> Backend, FBackendArray& PushArray)
{
checkf(!AllBackends.Contains(Backend), TEXT("Adding the same virtualization backend (%s) multiple times!"), *Backend->GetDebugName());
// Move ownership of the backend to AllBackends
AllBackends.Add(MoveTemp(Backend));
// Get a reference pointer to use in the other backend arrays
IVirtualizationBackend* BackendRef = AllBackends.Last().Get();
if (BackendRef->IsOperationSupported(IVirtualizationBackend::EOperations::Pull))
{
PullEnabledBackends.Add(BackendRef);
}
if (BackendRef->IsOperationSupported(IVirtualizationBackend::EOperations::Push))
{
PushArray.Add(BackendRef);
}
COOK_STAT(Profiling::CreateStats(*BackendRef));
}
void FVirtualizationManager::CachePayload(const FIoHash& Id, const FCompressedBuffer& Payload, const IVirtualizationBackend* BackendSource)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FVirtualizationManager::CachePayload);
// We start caching at the first (assumed to be fastest) local cache backend.
for (IVirtualizationBackend* BackendToCache : LocalCachableBackends)
{
if (BackendToCache == BackendSource)
{
return; // No point going past BackendSource
}
const bool bResult = TryCacheDataToBackend(*BackendToCache, Id, Payload);
UE_CLOG( !bResult, LogVirtualization, Warning,
TEXT("Failed to cache payload '%s' to backend '%s'"),
*LexToString(Id),
*BackendToCache->GetDebugName());
// Debug operation to validate that the payload we just cached can be retrieved from storage
if (DebugValues.bValidateAfterPush && bResult && BackendToCache->IsOperationSupported(IVirtualizationBackend::EOperations::Pull))
{
FCompressedBuffer PulledPayload = PullDataFromBackend(*BackendToCache, Id);
checkf( Payload.GetRawHash() == PulledPayload.GetRawHash(),
TEXT("[%s] Failed to pull payload '%s' after it was cached to backend"),
*BackendToCache->GetDebugName(),
*LexToString(Id));
}
}
}
bool FVirtualizationManager::TryCacheDataToBackend(IVirtualizationBackend& Backend, const FIoHash& Id, const FCompressedBuffer& Payload)
{
COOK_STAT(FCookStats::FScopedStatsCounter Timer(Profiling::GetCacheStats(Backend)));
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
const EPushResult Result = Backend.PushData(Id, Payload, FString());
if (Result == EPushResult::Success)
{
COOK_STAT(Timer.AddHit(Payload.GetCompressedSize()));
}
return Result != EPushResult::Failed;
}
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
bool FVirtualizationManager::TryPushDataToBackend(IVirtualizationBackend& Backend, TArrayView<FPushRequest> Requests)
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
{
COOK_STAT(FCookStats::CallStats & Stats = Profiling::GetPushStats(Backend));
COOK_STAT(FCookStats::FScopedStatsCounter Timer(Stats));
COOK_STAT(Timer.TrackCyclesOnly());
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
const bool bPushResult = Backend.PushData(Requests);
#if ENABLE_COOK_STATS
if (bPushResult)
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
{
Timer.AddHit(0);
const bool bIsInGameThread = IsInGameThread();
for (const FPushRequest& Request : Requests)
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
{
// TODO: Don't add a hit if the payload was already uploaded
When virtualizing payloads we now load the payloads from disk on demand rather than all at once. This allows us to avoid memory spikes when virtualizing large amounts of data. #rb Per.Larsson #rnx #jira UE-151000 #preflight 627271c83b2ed6f85363f53a - In the old code when submitting packages for virtualization we would load all local payloads into memory then pass them to the virtualization system to be pushed to persistent storage. This works fine for an average users submits but when resaving large projects we can have submits with thousands of packages containing gigabytes of payloads. - FPushRequest has been changed to accept either a payload directly (in the form of FCompressedBuffer) or accept a reference to a IPayloadProvider which will return the payload when asked. - Most of the existing backends make no use of the batched pushing feature and only push one payload at a time. The default implementation of this will be to ask each request one at a time for the payload and then pass it to the backend for a single push. If the IPayloadProvider is being used we will therefor only ever have one payload loaded at a time avoiding memory spikes. - The source control backend currently does implement the batched pushing feature. This backend writes each payload to disk before submitting them to perforce, so all we have to do is make sure that request one payload, write it to disk, then discard the payload to avoid memory spikes. - This change required that FPushRequest make it's members private and provide accessors to them, as the caller shouldn't need to care if the payload is loaded or comes via the provider. - NOTE that this implementation is less efficient if we have packages containing many different payloads as we will end up opening the package, parsing the trailer then load a payload many times over, where as the original code would load all payloads from the file in one go. In practice, given the overhead of the source control backend this didn't make a huge difference and is probably not worth the effort to optimize at this point. [CL 20040609 by paul chipchase in ue5-main branch]
2022-05-04 08:58:50 -04:00
if (Request.GetStatus() == FPushRequest::EStatus::Success)
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
{
Stats.Accumulate(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Counter, 1l, bIsInGameThread);
When virtualizing payloads we now load the payloads from disk on demand rather than all at once. This allows us to avoid memory spikes when virtualizing large amounts of data. #rb Per.Larsson #rnx #jira UE-151000 #preflight 627271c83b2ed6f85363f53a - In the old code when submitting packages for virtualization we would load all local payloads into memory then pass them to the virtualization system to be pushed to persistent storage. This works fine for an average users submits but when resaving large projects we can have submits with thousands of packages containing gigabytes of payloads. - FPushRequest has been changed to accept either a payload directly (in the form of FCompressedBuffer) or accept a reference to a IPayloadProvider which will return the payload when asked. - Most of the existing backends make no use of the batched pushing feature and only push one payload at a time. The default implementation of this will be to ask each request one at a time for the payload and then pass it to the backend for a single push. If the IPayloadProvider is being used we will therefor only ever have one payload loaded at a time avoiding memory spikes. - The source control backend currently does implement the batched pushing feature. This backend writes each payload to disk before submitting them to perforce, so all we have to do is make sure that request one payload, write it to disk, then discard the payload to avoid memory spikes. - This change required that FPushRequest make it's members private and provide accessors to them, as the caller shouldn't need to care if the payload is loaded or comes via the provider. - NOTE that this implementation is less efficient if we have packages containing many different payloads as we will end up opening the package, parsing the trailer then load a payload many times over, where as the original code would load all payloads from the file in one go. In practice, given the overhead of the source control backend this didn't make a huge difference and is probably not worth the effort to optimize at this point. [CL 20040609 by paul chipchase in ue5-main branch]
2022-05-04 08:58:50 -04:00
Stats.Accumulate(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Bytes, Request.GetPayloadSize(), bIsInGameThread);
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
}
}
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
}
#endif // ENABLE_COOK_STATS
Packages submitted from the editor together will now virtualize their payloads in a single batch rather than one at a time. #rb PJ.Kack #jira UE-136126 #rnx #preflight ### VirtualizationSystem - Added a new overload for Push to VirtualizationSystem that takes an array of FPushRequest, which is a new structure representing a single payload request. - Filtering by package name is currently disabled, this is because the API has been forced into changing and passing the package name in via a FString rather than FPackagePath which means we would need to be more careful. This will be done in a future submit. - The backend interface has been extended to also have a batch version of PushData, by default this will attempt to submit each request one at a time so payloads don't have to try and implement a batched version if there is no need. - The context being passed with a payload when being pushed has been changed from FPackagePath to FString due to include order issues, as the FPackagePath lives in CoreUObject and the API for virtualization lives in Core. Additionally in the future the payloads might not be owned by a package (there is nothing specifically enforcing this) so the context being a string makes more sense. - NOTE: Due to the context change we currently no longer support the filtering feature, which allows for payloads belonging to packages under specific directories to be excluded from virtualization. This is something that will be solved in a future submit. ### SourceControlBackend - Now that we can submit multiple payloads in the same submit, the CL description has been changed slightly. We will now print a list of payload identifiers -> the package trying to submit that payload. This will only tell the users which package originally caused the payload to submit. If a user submits a new package at a later date that contains the same payload we will not be updating the description. ### PackageSubmissionChecks - Converted the submission process to use the new batch push operation in VirtualizationSystem. -- This means that we do a single push and then have to update the package trailers to convert the now pushed payloads from local to virtualized. - Added new define UE_PRECHECK_PAYLOAD_STATUS that makes it easy to toggle off the checks to see which payloads need to be submitted to the persistent backend. This is useful to test if it actually helps speed up the overall operations or if it is faster to just perform the batch push operations on all payloads and check the return values. -- The hope is that over time the submission processes will become fast enough that we can remove the precheck. - Fixed up logging to not always assume more than one package or payload. ### General Notes - Errors and logging is now a bit more vague as we often not just report that X payloads failed etc rather than specific payload identifiers. This probably doesn't affect the user too much since those identifiers as fairly meaningless to them anyway. - The source control submission could be further optimized by first checking the status of the files in thge depot and only then creating/switching workspace etc. - As currently written, we need to load all of the payloads into memory, then the backends will do what they need (in the case of source control this results in the payloads being written to disk then submitted) which could create quite a large memory spike when submitting a large number of packages. -- One solution would be to change the batch push API to take a "payload provider" interface and have the payloads requested as needed rather than passing in the FCompressedBuffer directly. This would let us immediately write the payload to disk for submission then discard it from memory, preventing larger spikes. Although it could cause overhead if there are multiple backends being submitted to. Internally we are unlikely to have more than one backend per storage solution so maybe we should just make it a config option? #ROBOMERGE-AUTHOR: paul.chipchase #ROBOMERGE-SOURCE: CL 18403735 in //UE5/Release-5.0/... via CL 18403737 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18403738 by paul chipchase in ue5-release-engine-test branch]
2021-12-08 02:19:42 -05:00
return bPushResult;
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
}
FCompressedBuffer FVirtualizationManager::PullDataFromAllBackends(const FIoHash& Id)
{
if (ShouldDebugFailPulling())
{
UE_LOG(LogVirtualization, Verbose, TEXT("Debug miss chance (%.1f%%) invoked when pulling payload '%s'"), DebugValues.MissChance, *LexToString(Id));
return FCompressedBuffer();
}
for (IVirtualizationBackend* Backend : PullEnabledBackends)
{
// Skip if pulling has been disabled on this backend for debug purposes
if (Backend->IsOperationDebugDisabled(IVirtualizationBackend::EOperations::Pull))
{
UE_LOG(LogVirtualization, Verbose, TEXT("Pulling from backend '%s' is debug disabled for payload '%s'"), *Backend->GetDebugName(), *LexToString(Id));
continue;
}
FCompressedBuffer Payload = PullDataFromBackend(*Backend, Id);
if (Payload)
{
if (bEnableCacheAfterPull)
{
CachePayload(Id, Payload, Backend);
}
UE_LOG(LogVirtualization, VeryVerbose, TEXT("[%s] pulled payload '%s'"), *Backend->GetDebugName(), *LexToString(Id));
return Payload;
}
}
return FCompressedBuffer();
}
FCompressedBuffer FVirtualizationManager::PullDataFromBackend(IVirtualizationBackend& Backend, const FIoHash& Id)
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
{
COOK_STAT(FCookStats::FScopedStatsCounter Timer(Profiling::GetPullStats(Backend)));
FCompressedBuffer Payload = Backend.PullData(Id);
if (!Payload.IsNull())
{
COOK_STAT(Timer.AddHit(Payload.GetCompressedSize()));
}
return Payload;
}
bool FVirtualizationManager::ShouldVirtualizePackage(const FPackagePath& PackagePath) const
{
TRACE_CPUPROFILER_EVENT_SCOPE(FVirtualizationManager::ShouldVirtualizePackage);
// We require a valid mounted path for filtering
if (!PackagePath.IsMountedPath())
{
return true;
}
TStringBuilder<256> PackageName;
PackagePath.AppendPackageName(PackageName);
TStringBuilder<64> MountPointName;
TStringBuilder<256> MountPointPath;
TStringBuilder<256> RelativePath;
if (!FPackageName::TryGetMountPointForPath(PackageName, MountPointName, MountPointPath, RelativePath))
{
return true;
}
if (bFilterEngineContent)
{
// Do not virtualize engine content
if (MountPointName.ToView() == TEXT("/Engine/"))
{
return false;
}
}
if (bFilterEnginePluginContent)
{
// Do not virtualize engine plugin content
if (FPaths::IsUnderDirectory(MountPointPath.ToString(), FPaths::EnginePluginsDir()))
{
return false;
}
}
const UVirtualizationFilterSettings* Settings = GetDefault<UVirtualizationFilterSettings>();
if (Settings != nullptr)
{
Allow the virtualization of assets to be opt in, as well as opt out. This would allow a project to selectively turn on virtualization for specific locations or plugins rather than for the whole project by default. #rb PJ.Kack #jira UE-133473 #preflight 620bf6ae483ff0ae5ec22257 ### VirtualizationManager - Added EPackageFilterMode that can be set via [Core.ContentVirtualization] in the config file to control the default virtualization behavior. -- When set to EPackageFilterMode::OptOut(the default) all package paths will virtualize unless excluded by a pattern in UVirtualizationFilterSettings::ExcludePackagePaths. -- When set to EPackageFilterMode::OptIn then no package path will virtualize unless included by a pattern in UVirtualizationFilterSettings::IncludePackagePaths. - Added a TRACE_CPUPROFILER_EVENT_SCOPE to the constructor and ::MountBackends to better track the set up time costs. - Change use of FConfigCacheIni::LoadLocalIniFile to use GConfig, there is no need to load our own. - Improved verbose logging to show when a payload is rejected via filtering. - We now early out if all payloads being requested in a push are rejected during validation. - Renamed the FString overload for ::ShouldVirtualizePackage to ::ShouldVirtualize to make the difference clearer. - Added support for UVirtualizationFilterSettings::ExcludePackagePaths when filtering ### UVirtualizationFilterSettings - Now has a new FString array ExcludePackagePaths, which contains the paths/patterns used to force packages to be virtualized when filtering. [CL 19010992 by paul chipchase in ue5-main branch]
2022-02-16 01:27:09 -05:00
auto DoesMatch = [](const TArray<FString>& Paths, const FStringView& PackagePath) -> bool
{
Allow the virtualization of assets to be opt in, as well as opt out. This would allow a project to selectively turn on virtualization for specific locations or plugins rather than for the whole project by default. #rb PJ.Kack #jira UE-133473 #preflight 620bf6ae483ff0ae5ec22257 ### VirtualizationManager - Added EPackageFilterMode that can be set via [Core.ContentVirtualization] in the config file to control the default virtualization behavior. -- When set to EPackageFilterMode::OptOut(the default) all package paths will virtualize unless excluded by a pattern in UVirtualizationFilterSettings::ExcludePackagePaths. -- When set to EPackageFilterMode::OptIn then no package path will virtualize unless included by a pattern in UVirtualizationFilterSettings::IncludePackagePaths. - Added a TRACE_CPUPROFILER_EVENT_SCOPE to the constructor and ::MountBackends to better track the set up time costs. - Change use of FConfigCacheIni::LoadLocalIniFile to use GConfig, there is no need to load our own. - Improved verbose logging to show when a payload is rejected via filtering. - We now early out if all payloads being requested in a push are rejected during validation. - Renamed the FString overload for ::ShouldVirtualizePackage to ::ShouldVirtualize to make the difference clearer. - Added support for UVirtualizationFilterSettings::ExcludePackagePaths when filtering ### UVirtualizationFilterSettings - Now has a new FString array ExcludePackagePaths, which contains the paths/patterns used to force packages to be virtualized when filtering. [CL 19010992 by paul chipchase in ue5-main branch]
2022-02-16 01:27:09 -05:00
for (const FString& PathToMatch : Paths)
{
Allow the virtualization of assets to be opt in, as well as opt out. This would allow a project to selectively turn on virtualization for specific locations or plugins rather than for the whole project by default. #rb PJ.Kack #jira UE-133473 #preflight 620bf6ae483ff0ae5ec22257 ### VirtualizationManager - Added EPackageFilterMode that can be set via [Core.ContentVirtualization] in the config file to control the default virtualization behavior. -- When set to EPackageFilterMode::OptOut(the default) all package paths will virtualize unless excluded by a pattern in UVirtualizationFilterSettings::ExcludePackagePaths. -- When set to EPackageFilterMode::OptIn then no package path will virtualize unless included by a pattern in UVirtualizationFilterSettings::IncludePackagePaths. - Added a TRACE_CPUPROFILER_EVENT_SCOPE to the constructor and ::MountBackends to better track the set up time costs. - Change use of FConfigCacheIni::LoadLocalIniFile to use GConfig, there is no need to load our own. - Improved verbose logging to show when a payload is rejected via filtering. - We now early out if all payloads being requested in a push are rejected during validation. - Renamed the FString overload for ::ShouldVirtualizePackage to ::ShouldVirtualize to make the difference clearer. - Added support for UVirtualizationFilterSettings::ExcludePackagePaths when filtering ### UVirtualizationFilterSettings - Now has a new FString array ExcludePackagePaths, which contains the paths/patterns used to force packages to be virtualized when filtering. [CL 19010992 by paul chipchase in ue5-main branch]
2022-02-16 01:27:09 -05:00
if (PathToMatch.EndsWith(TEXT("/")))
{
Allow the virtualization of assets to be opt in, as well as opt out. This would allow a project to selectively turn on virtualization for specific locations or plugins rather than for the whole project by default. #rb PJ.Kack #jira UE-133473 #preflight 620bf6ae483ff0ae5ec22257 ### VirtualizationManager - Added EPackageFilterMode that can be set via [Core.ContentVirtualization] in the config file to control the default virtualization behavior. -- When set to EPackageFilterMode::OptOut(the default) all package paths will virtualize unless excluded by a pattern in UVirtualizationFilterSettings::ExcludePackagePaths. -- When set to EPackageFilterMode::OptIn then no package path will virtualize unless included by a pattern in UVirtualizationFilterSettings::IncludePackagePaths. - Added a TRACE_CPUPROFILER_EVENT_SCOPE to the constructor and ::MountBackends to better track the set up time costs. - Change use of FConfigCacheIni::LoadLocalIniFile to use GConfig, there is no need to load our own. - Improved verbose logging to show when a payload is rejected via filtering. - We now early out if all payloads being requested in a push are rejected during validation. - Renamed the FString overload for ::ShouldVirtualizePackage to ::ShouldVirtualize to make the difference clearer. - Added support for UVirtualizationFilterSettings::ExcludePackagePaths when filtering ### UVirtualizationFilterSettings - Now has a new FString array ExcludePackagePaths, which contains the paths/patterns used to force packages to be virtualized when filtering. [CL 19010992 by paul chipchase in ue5-main branch]
2022-02-16 01:27:09 -05:00
// Directory path, exclude everything under it
if (PackagePath.StartsWith(PathToMatch))
{
return true;
}
}
else
{
// Path to an asset, exclude if it matches exactly
if (PackagePath == PathToMatch)
{
return true;
}
}
}
Allow the virtualization of assets to be opt in, as well as opt out. This would allow a project to selectively turn on virtualization for specific locations or plugins rather than for the whole project by default. #rb PJ.Kack #jira UE-133473 #preflight 620bf6ae483ff0ae5ec22257 ### VirtualizationManager - Added EPackageFilterMode that can be set via [Core.ContentVirtualization] in the config file to control the default virtualization behavior. -- When set to EPackageFilterMode::OptOut(the default) all package paths will virtualize unless excluded by a pattern in UVirtualizationFilterSettings::ExcludePackagePaths. -- When set to EPackageFilterMode::OptIn then no package path will virtualize unless included by a pattern in UVirtualizationFilterSettings::IncludePackagePaths. - Added a TRACE_CPUPROFILER_EVENT_SCOPE to the constructor and ::MountBackends to better track the set up time costs. - Change use of FConfigCacheIni::LoadLocalIniFile to use GConfig, there is no need to load our own. - Improved verbose logging to show when a payload is rejected via filtering. - We now early out if all payloads being requested in a push are rejected during validation. - Renamed the FString overload for ::ShouldVirtualizePackage to ::ShouldVirtualize to make the difference clearer. - Added support for UVirtualizationFilterSettings::ExcludePackagePaths when filtering ### UVirtualizationFilterSettings - Now has a new FString array ExcludePackagePaths, which contains the paths/patterns used to force packages to be virtualized when filtering. [CL 19010992 by paul chipchase in ue5-main branch]
2022-02-16 01:27:09 -05:00
return false;
};
const FStringView PackageNameView = PackageName.ToView();
if (DoesMatch(Settings->ExcludePackagePaths, PackageNameView))
{
return false;
}
if (DoesMatch(Settings->IncludePackagePaths, PackageNameView))
{
return true;
}
}
Allow the virtualization of assets to be opt in, as well as opt out. This would allow a project to selectively turn on virtualization for specific locations or plugins rather than for the whole project by default. #rb PJ.Kack #jira UE-133473 #preflight 620bf6ae483ff0ae5ec22257 ### VirtualizationManager - Added EPackageFilterMode that can be set via [Core.ContentVirtualization] in the config file to control the default virtualization behavior. -- When set to EPackageFilterMode::OptOut(the default) all package paths will virtualize unless excluded by a pattern in UVirtualizationFilterSettings::ExcludePackagePaths. -- When set to EPackageFilterMode::OptIn then no package path will virtualize unless included by a pattern in UVirtualizationFilterSettings::IncludePackagePaths. - Added a TRACE_CPUPROFILER_EVENT_SCOPE to the constructor and ::MountBackends to better track the set up time costs. - Change use of FConfigCacheIni::LoadLocalIniFile to use GConfig, there is no need to load our own. - Improved verbose logging to show when a payload is rejected via filtering. - We now early out if all payloads being requested in a push are rejected during validation. - Renamed the FString overload for ::ShouldVirtualizePackage to ::ShouldVirtualize to make the difference clearer. - Added support for UVirtualizationFilterSettings::ExcludePackagePaths when filtering ### UVirtualizationFilterSettings - Now has a new FString array ExcludePackagePaths, which contains the paths/patterns used to force packages to be virtualized when filtering. [CL 19010992 by paul chipchase in ue5-main branch]
2022-02-16 01:27:09 -05:00
// The package is not in any of the include/exclude paths so we use the default behavior
return ShouldVirtualizeAsDefault();
}
Allow the virtualization of assets to be opt in, as well as opt out. This would allow a project to selectively turn on virtualization for specific locations or plugins rather than for the whole project by default. #rb PJ.Kack #jira UE-133473 #preflight 620bf6ae483ff0ae5ec22257 ### VirtualizationManager - Added EPackageFilterMode that can be set via [Core.ContentVirtualization] in the config file to control the default virtualization behavior. -- When set to EPackageFilterMode::OptOut(the default) all package paths will virtualize unless excluded by a pattern in UVirtualizationFilterSettings::ExcludePackagePaths. -- When set to EPackageFilterMode::OptIn then no package path will virtualize unless included by a pattern in UVirtualizationFilterSettings::IncludePackagePaths. - Added a TRACE_CPUPROFILER_EVENT_SCOPE to the constructor and ::MountBackends to better track the set up time costs. - Change use of FConfigCacheIni::LoadLocalIniFile to use GConfig, there is no need to load our own. - Improved verbose logging to show when a payload is rejected via filtering. - We now early out if all payloads being requested in a push are rejected during validation. - Renamed the FString overload for ::ShouldVirtualizePackage to ::ShouldVirtualize to make the difference clearer. - Added support for UVirtualizationFilterSettings::ExcludePackagePaths when filtering ### UVirtualizationFilterSettings - Now has a new FString array ExcludePackagePaths, which contains the paths/patterns used to force packages to be virtualized when filtering. [CL 19010992 by paul chipchase in ue5-main branch]
2022-02-16 01:27:09 -05:00
bool FVirtualizationManager::ShouldVirtualize(const FString& Context) const
{
Allow the virtualization of assets to be opt in, as well as opt out. This would allow a project to selectively turn on virtualization for specific locations or plugins rather than for the whole project by default. #rb PJ.Kack #jira UE-133473 #preflight 620bf6ae483ff0ae5ec22257 ### VirtualizationManager - Added EPackageFilterMode that can be set via [Core.ContentVirtualization] in the config file to control the default virtualization behavior. -- When set to EPackageFilterMode::OptOut(the default) all package paths will virtualize unless excluded by a pattern in UVirtualizationFilterSettings::ExcludePackagePaths. -- When set to EPackageFilterMode::OptIn then no package path will virtualize unless included by a pattern in UVirtualizationFilterSettings::IncludePackagePaths. - Added a TRACE_CPUPROFILER_EVENT_SCOPE to the constructor and ::MountBackends to better track the set up time costs. - Change use of FConfigCacheIni::LoadLocalIniFile to use GConfig, there is no need to load our own. - Improved verbose logging to show when a payload is rejected via filtering. - We now early out if all payloads being requested in a push are rejected during validation. - Renamed the FString overload for ::ShouldVirtualizePackage to ::ShouldVirtualize to make the difference clearer. - Added support for UVirtualizationFilterSettings::ExcludePackagePaths when filtering ### UVirtualizationFilterSettings - Now has a new FString array ExcludePackagePaths, which contains the paths/patterns used to force packages to be virtualized when filtering. [CL 19010992 by paul chipchase in ue5-main branch]
2022-02-16 01:27:09 -05:00
// First see if we can convert the context from a raw string to a valid package path.
// If we can extract a package path then we should use the package filtering code
// path instead.
FPackagePath PackagePath;
if (FPackagePath::TryFromPackageName(Context, PackagePath))
{
return ShouldVirtualizePackage(PackagePath);
}
if (FPackagePath::TryFromMountedName(Context, PackagePath))
{
return ShouldVirtualizePackage(PackagePath);
}
Allow the virtualization of assets to be opt in, as well as opt out. This would allow a project to selectively turn on virtualization for specific locations or plugins rather than for the whole project by default. #rb PJ.Kack #jira UE-133473 #preflight 620bf6ae483ff0ae5ec22257 ### VirtualizationManager - Added EPackageFilterMode that can be set via [Core.ContentVirtualization] in the config file to control the default virtualization behavior. -- When set to EPackageFilterMode::OptOut(the default) all package paths will virtualize unless excluded by a pattern in UVirtualizationFilterSettings::ExcludePackagePaths. -- When set to EPackageFilterMode::OptIn then no package path will virtualize unless included by a pattern in UVirtualizationFilterSettings::IncludePackagePaths. - Added a TRACE_CPUPROFILER_EVENT_SCOPE to the constructor and ::MountBackends to better track the set up time costs. - Change use of FConfigCacheIni::LoadLocalIniFile to use GConfig, there is no need to load our own. - Improved verbose logging to show when a payload is rejected via filtering. - We now early out if all payloads being requested in a push are rejected during validation. - Renamed the FString overload for ::ShouldVirtualizePackage to ::ShouldVirtualize to make the difference clearer. - Added support for UVirtualizationFilterSettings::ExcludePackagePaths when filtering ### UVirtualizationFilterSettings - Now has a new FString array ExcludePackagePaths, which contains the paths/patterns used to force packages to be virtualized when filtering. [CL 19010992 by paul chipchase in ue5-main branch]
2022-02-16 01:27:09 -05:00
// The package is not in any of the include/exclude paths so we use the default behavior
return ShouldVirtualizeAsDefault();
}
bool FVirtualizationManager::ShouldVirtualizeAsDefault() const
{
switch (FilteringMode)
{
case EPackageFilterMode::OptOut:
return true;
case EPackageFilterMode::OptIn:
return false;
default:
checkNoEntry();
return false;
}
}
} // namespace UE::Virtualization
#undef LOCTEXT_NAMESPACE