UnattendedRetryCount
UnattendedRetryCount
#Overview
name: UnattendedRetryCount
The value of this variable can be defined or overridden in .ini config files. 1
.ini config file referencing this setting variable.
It is referenced in 5
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of UnattendedRetryCount is to control the number of retry attempts for pulling payloads in unattended processes within Unreal Engine’s virtualization system. This setting is particularly useful for handling network-related issues or temporary failures in automated environments.
The Unreal Engine subsystem that relies on this setting variable is the Virtualization system, specifically within the UE::Virtualization namespace. This is evident from the references in the VirtualizationManager.cpp and VirtualizationManager.h files.
The value of this variable is set in the ApplySettingsFromConfigFiles function of the FVirtualizationManager class. It reads the value from a configuration file using the ConfigFile.GetInt method.
UnattendedRetryCount interacts with other variables such as UnattendedRetryTimer and UnattendedFailureMsgCount. These variables work together to manage the retry behavior in unattended processes.
Developers must be aware that:
- Setting UnattendedRetryCount to zero or a negative value disables the retry system.
- The actual number of retries may be less than UnattendedRetryCount if the process encounters multiple simultaneous errors.
- This setting is particularly important for build machines or automated processes with unreliable network connections.
Best practices when using this variable include:
- Set a reasonable value based on the reliability of your network and infrastructure.
- Use in conjunction with UnattendedRetryTimer to implement a backoff strategy.
- Monitor logs to ensure the retry system is functioning as expected and adjust values if necessary.
- Consider the trade-off between potential recovery and extended process runtime when setting this value.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseEngine.ini:1480, section: [Core.VirtualizationModule]
- INI Section:
Core.VirtualizationModule
- Raw value:
0
- Is Array:
False
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Developer/Virtualization/Private/VirtualizationManager.cpp:1221
Scope (from outer to inner):
file
namespace UE::Virtualization
function void FVirtualizationManager::ApplySettingsFromConfigFiles
Source code excerpt:
{
ConfigFile.GetInt(ConfigSection, TEXT("UnattendedRetryTimer"), UnattendedRetryTimer);
ConfigFile.GetInt(ConfigSection, TEXT("UnattendedRetryCount"), UnattendedRetryCount);
if (ShouldRetryWhenUnattended())
{
UE_LOG(LogVirtualization, Display, TEXT("\tUnattendedRetryTimer : %d retries every %d(s)"), UnattendedRetryCount, UnattendedRetryTimer);
}
else
{
UE_LOG(LogVirtualization, Display, TEXT("\tUnattendedRetries : disabled"));
}
}
#Loc: <Workspace>/Engine/Source/Developer/Virtualization/Private/VirtualizationManager.cpp:2089
Scope (from outer to inner):
file
namespace UE::Virtualization
function FVirtualizationManager::ErrorHandlingResult FVirtualizationManager::OnPayloadPullError
Source code excerpt:
const FText Message = MsgBuilder.ToText();
if (!ShouldRetryWhenUnattended() || UnattendedFailureMsgCount >= UnattendedRetryCount)
{
UE_LOG(LogVirtualization, Error, TEXT("%s"), *Message.ToString());
}
else
{
// Only log as a warning while we are retrying so that if we do recover out logging will
// not cause the running process to be considered a failure due to an error.
UE_LOG(LogVirtualization, Warning, TEXT("Failed to pull payload(s) on attempt (%d/%d)"), UnattendedFailureMsgCount.load(), UnattendedRetryCount);
Result = EAppReturnType::Yes; // Attempt to retry the failed pull
if (UnattendedRetryTimer > 0)
{
UE_LOG(LogVirtualization, Warning, TEXT("Waiting for %d seconds before trying to pull again..."), UnattendedRetryTimer);
#Loc: <Workspace>/Engine/Source/Developer/Virtualization/Private/VirtualizationManager.cpp:2260
Scope (from outer to inner):
file
namespace UE::Virtualization
function bool FVirtualizationManager::ShouldRetryWhenUnattended
Source code excerpt:
bool FVirtualizationManager::ShouldRetryWhenUnattended() const
{
return UnattendedRetryCount > 0;
}
void FVirtualizationManager::BroadcastEvent(TConstArrayView<FPullRequest> Requests, ENotification Event)
{
for (const FPullRequest& Request : Requests)
{
#Loc: <Workspace>/Engine/Source/Developer/Virtualization/Private/VirtualizationManager.h:135
Scope: file
Source code excerpt:
* expensive existence checks, or if a backend is in a bad state where it believes it has the payload
* but is unable to actually return the data. [Default=false]
* UnattendedRetryCount [int32]: How many times the process should retry pulling payloads after a failure is encountered if the
process is unattended. Usually when a payload pull fails we ask the user to try and fix the issue
and retry, but in unattended mode we just log an error and terminate the process. In some cases
such as build machines with unreliable internet it is possible that the process could recover in
which case setting this value might help. Zero or negative values will disable the system.
Note: If many pulls are occurring at the same time on many threads a very short network outage might
spawn many errors in which case we try to group these errors into a single 'try' so 32 errors on 32
threads would not immediately blow past a retry count of 30 for example. [Default=0]
* UnattendedRetryTimer [int32] If 'UnattendedRetryCount' is set to a positive value then this value sets how long (in seconds)
* the process should wait after a failure is encountered before retrying the pull. Depending on the
likely cause of the failure you may want to set this value to several minutes. [Default=0]
*/
namespace UE::Virtualization
{
class FPullRequestCollection;
/** The default mode of filtering to use with package paths that do not match entries in UVirtualizationFilterSettings */
enum class EPackageFilterMode : uint8
{
/** Packages will be virtualized by default and must be opted out by the use of UVirtualizationFilterSettings::ExcludePackagePaths */
OptOut = 0,
/** Packages will not be virtualized by default and must be opted in by the user of UVirtualizationFilterSettings::IncludePackagePaths */
OptIn
};
/** Attempt to convert a string buffer to EPackageFilterMode */
bool LexTryParseString(EPackageFilterMode& OutValue, FStringView Buffer);
/** This is used as a wrapper around the various potential back end implementations.
The calling code shouldn't need to care about which back ends are actually in use. */
class FVirtualizationManager final : public IVirtualizationSystem
{
public:
using FRegistedFactories = TMap<FName, IVirtualizationBackendFactory*>;
using FBackendArray = TArray<IVirtualizationBackend*>;
FVirtualizationManager();
virtual ~FVirtualizationManager();
private:
/* IVirtualizationSystem implementation */
virtual bool Initialize(const FInitParams& InitParams) override;
virtual bool IsEnabled() const override;
virtual bool IsPushingEnabled(EStorageType StorageType) const override;
virtual EPayloadFilterReason FilterPayload(const UObject* Owner) const override;
virtual bool AllowSubmitIfVirtualizationFailed() const override;
virtual bool PushData(TArrayView<FPushRequest> Requests, EStorageType StorageType) override;
virtual bool PullData(TArrayView<FPullRequest> Requests) override;
virtual EQueryResult QueryPayloadStatuses(TArrayView<const FIoHash> Ids, EStorageType StorageType, TArray<EPayloadStatus>& OutStatuses) override;
virtual FVirtualizationResult TryVirtualizePackages(TConstArrayView<FString> PackagePaths, EVirtualizationOptions Options) override;
virtual FRehydrationResult TryRehydratePackages(TConstArrayView<FString> PackagePaths, ERehydrationOptions Options) override;
virtual ERehydrationResult TryRehydratePackages(TConstArrayView<FString> PackagePaths, uint64 PaddingAlignment, TArray<FText>& OutErrors, TArray<FSharedBuffer>& OutPackages, TArray<FRehydrationInfo>* OutInfo) override;
virtual void DumpStats() const override;
virtual FPayloadActivityInfo GetAccumualtedPayloadActivityInfo() const override;
virtual void GetPayloadActivityInfo( GetPayloadActivityInfoFuncRef ) const override;
virtual void GatherAnalytics(TArray<FAnalyticsEventAttribute>& Attributes) const override;
virtual FOnNotification& GetNotificationEvent() override
{
return NotificationEvent;
}
#Loc: <Workspace>/Engine/Source/Developer/Virtualization/Private/VirtualizationManager.h:347
Scope (from outer to inner):
file
namespace UE::Virtualization
class class FVirtualizationManager final : public IVirtualizationSystem
Source code excerpt:
/** The number of times to retry pulling when errors are encountered in an unattended process, values <0 disable the system */
int32 UnattendedRetryCount = 0;
/** The how long (in seconds) to wait after payload pulling errors before retrying. Does nothing if 'UnattendedRetryCount' is disabled */
int32 UnattendedRetryTimer = 0;
private:
/** The name of the current project */
FString ProjectName;