2021-12-02 06:21:36 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
# pragma once
# include "IVirtualizationBackend.h"
# include "Containers/StringView.h"
2022-03-08 11:22:45 -05:00
class ISourceControlProvider ;
2021-12-02 06:21:36 -05:00
namespace UE : : Virtualization
{
2022-05-03 09:39:48 -04:00
class FSemaphore ;
2021-12-02 06:21:36 -05:00
/**
* This backend can be used to access payloads stored in source control .
* The backend doesn ' t ' check out ' a payload file but instead will just download the payload as
* a binary blob .
* It is assumed that the files are stored with the same path convention as the file system
* backend , found in Utils : : PayloadIdToPath .
2023-03-20 09:49:52 -04:00
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
2021-12-02 06:21:36 -05:00
* Ini file setup :
2023-04-13 10:11:47 -04:00
* ' Name ' = ( Type = P4SourceControl )
* Where ' Name ' is the backend name in the hierarchy
2021-12-07 03:21:51 -05:00
*
2023-04-13 10:11:47 -04:00
* Required Values :
*
2023-06-20 04:26:06 -04:00
* DepotPath [ string ] The path ( in depot format ) to the location where virtualized payloads are stored .
* [ Default = " " ]
* ClientStream [ string ] : Used when the payloads are stored in a stream based depot . It should contain
* the stream name to use when creating a workspace for payload submission . [ Default = " " ]
2023-04-13 10:11:47 -04:00
*
* If the payloads are being stored in a depot with type ' stream ' them config value ' ClientStream ' must be set to a valid
* stream . The ' DepotPath ' value can still be set to choose a specific location within that stream or when the stream
* name is not a valid depot path ( such as virtual streams )
*
* If the payloads are not being stored in a ' stream ' depot then only ' DepotPath ' is required .
*
* Optional Values :
*
2023-06-20 04:26:06 -04:00
* Server [ string ] : When set the backend will use this server address to connect to . When not
* set the backend will use the environment defaults . [ Default = " " ]
* UsePartitionedClient [ bool ] : When true the temporary workspace client created to submit payloads
* from will be created as a partitioned workspace which is less overhead
* on the source control server . If your server does not support this then
* use false . [ Default = True ]
* WorkingDir [ string ] : Sets the temp location on disk where payloads are submitted from . The path can
* contain config file expansions ( see ConfigCacheIni . cpp : : MatchExpansions ) and
* environment variables with the format $ ( EnvVarName ) .
* [ Default = " %GAMESAVEDDIR%/VASubmission " ]
* RetryCount [ int32 ] : How many times we should try to download a payload before giving up with
* an error . Useful when the connection is unreliable but does not experience
* frequent persistent outages . [ Default = 2 ]
* RetryWaitTime [ int32 ] : The length of time the process should wait between each download attempt
* in milliseconds . Remember that the max length of time that the process
* can stall attempting to download a payload file is
* RetryCount * RetryWaitTime ; [ Default = 100 ms ]
* MaxConnections [ int32 ] The maximum number of perforce connections that can be made concurrently .
* If this value is exceeded then additional requests will wait until a
* connection becomes free . Pass in ' - 1 ' to disable this feature and allow
* unlimited connections . [ Default = 8 ]
* BatchCount [ int32 ] The max number of payloads that can be pushed to source control in a
* single submit . If the number of payloads in a request batch exceeds
* this size then it will be split into multiple smaller batches . [ Default = 100 ]
* SuppressNotifications [ bool ] : When true the system will not display a pop up notification when a
* connection error occurs , allowing the user to stay unaware of the error
* unless it actually causes some sort of problem . [ Default = false ]
* UseLocalIniFileSettings [ bool ] When true the revision control provider will be allowed to load connection
* settings from the users locally saved ' SourceControlSettings . ini ' file , if
* false then the settings in this file ( if any ) will be ignored . [ Default = true ]
* IgnoreFile [ string ] : Sets the name of the p4 ignore file to use . When submitting payloads we
* create a custom p4 ignore file to override any ignore settings for a project
* which allows us to submit from the saved directory which is normally prevented
2024-01-10 07:53:41 -05:00
* by the default ignore file . This value should be set to the value of P4IGNORE
used by your environment . [ Default = " .p4ignore.txt " ]
2023-06-20 04:26:06 -04:00
* UseRetryConnectionDialog [ bool ] When true a slate dialog will be shown if the initial connection to the
* source control server fails allowing the user to attempt to input the correct
2024-01-10 07:53:41 -05:00
* login values . [ Default = false ]
2022-03-01 09:05:41 -05:00
*
* Environment Variables :
* UE - VirtualizationWorkingDir [ string ] : This can be set to a valid directory path that the backend
* should use as the root location to submit payloads from .
* If the users machine has this set then ' SubmitFromTempDir '
* will be ignored .
2023-03-20 09:49:52 -04:00
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
* Perforce Storage Setup :
*
* Once you have decided where in perforce you want to store the virtualized payloads you will need to submit
* a dummy file to the root of that location named " payload_metainfo.txt " preferably with a short message describing
* the storage locations purpose .
* When initialized this backend will first attempt to find and download this dummy file as a way of validating that
* a ) the process can correctly connect to perforce
* b ) the process has the correct location setup in the config file .
* This validation not only allows us to alert the user to misconfiguration issues before they need to access the data
* but allows us to prevent users from accidentally pushing virtualized payloads to the wrong location .
*
* So for example , if the virtualized payloads are to be stored under ' //payloads/project/...' then the backend would
* expect to find a ' //payloads/project/payload_metainfo.txt' file that it would download via a p4 print command.
*
* If this file is not found then the backend will log an error the first time that it attempts to connect and will prevent
* the user from pulling or pushing payloads until the issue is resolved .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
* Perforce Settings Setup :
2022-09-23 20:05:59 -04:00
*
* The backend will attempt to use the current global environment settings for perforce to determine
* the P4PORT and P4USER values . If you wish to set them via an ini file then they can be done per
* user by adding the following to Saved \ Config \ < platform > Editor \ SourceControlSettings . ini
*
* - - - - -
* [ PerforceSourceControl . VirtualizationSettings ]
* Port = < server address >
* UserName = < username >
* - - - - -
* Note that the backend will read from these ini file settings but will not write to them .
2021-12-02 06:21:36 -05:00
*/
class FSourceControlBackend final : public IVirtualizationBackend
{
public :
2022-03-08 11:22:45 -05:00
explicit FSourceControlBackend ( FStringView ProjectName , FStringView ConfigName , FStringView InDebugName ) ;
2021-12-02 06:21:36 -05:00
virtual ~ FSourceControlBackend ( ) = default ;
private :
/* IVirtualizationBackend implementation */
virtual bool Initialize ( const FString & ConfigEntry ) override ;
Add a number of ways for the VA backend connections to be changed to lazy initialize on first use.
#rb Devin.Doucette
#jira UE-161599
#rnx
#preflight 6303c8d65a5d4e4624e7bf52
- There are some use cases that require the VA system to be initialized and configured correctly but would prefer that the backend connections only run if absolutely needed (usually when a payload is pulled or pushed for the first time), this change provides four different ways of doing this:
-- Setting [Core.VirtualizationModule]LazyInitConnections=true in the Engine ini file
-- Setting the define 'UE_VIRTUALIZATION_CONNECTION_LAZY_INIT' to 1 in a programs .target.cs
-- Running with the commandline option -VA-LazyInitConnections
-- Setting the cvar 'VA.LazyInitConnections' to 1 (only works if it is set before the VA system is initialized, changing it mid editor via the console does nothing)
--- Note that after the config file, each setting there only opts into lazy initializing the connections, setting the cvar to 0 for example will not prevent the cmdline from opting in etc.
- In the future we will allow the connection code to run async, so the latency can be hidden behind the editor loading, but for the current use case we are taking the minimal approach.
-- This means we only support the backend being in 3 states. No connection has been made yet, the connection is broken and the connection is working.
-- To keep things simple we only record if we have attempted to connect the backends or not. We don't check individual backends nor do we try to reconnect failed ones etc. This is all scheduled for a future work item.
- If the connections are not initialized when the VA system is, we wait until the first time someone calls one of the virtualization methods that will actually use a connection: Push/Pull/Query
-- We try connecting all of the backends at once, even if they won't be used in the call to keep things simple.
- Only the source control backend makes use of the connection system. The horde storage (http) backend could take advantage too, but it is currently unused and most likely going to just be deleted so there seemed little point updating it.
- If we try to run an operation on an unconnected backend we only log to verbose. This is to maintain existing behaviour where a failed backend would not be mounted at all. This logging will likely be revisited in a future work item.
[CL 21511855 by paul chipchase in ue5-main branch]
2022-08-23 13:01:15 -04:00
virtual EConnectionStatus OnConnect ( ) override ;
2023-08-23 08:22:30 -04:00
IVirtualizationBackend : : EConnectionStatus OnConnectInternal ( FString & InOutPort , FString & InOutUsername , bool bSaveConnectionSettings , FText & OutErrorMessage ) ;
2021-12-02 06:21:36 -05:00
2023-04-14 10:13:46 -04:00
virtual bool PushData ( TArrayView < FPushRequest > Requests , EPushFlags Flags ) override ;
2023-04-25 08:47:06 -04:00
virtual bool PullData ( TArrayView < FPullRequest > Requests , EPullFlags Flags , FText & OutErrors ) override ;
2021-12-02 06:21:36 -05:00
2022-02-02 02:21:24 -05:00
virtual bool DoesPayloadExist ( const FIoHash & Id ) override ;
2021-12-02 06:21:36 -05:00
2022-02-02 02:21:24 -05:00
virtual bool DoPayloadsExist ( TArrayView < const FIoHash > PayloadIds , TArray < bool > & OutResults ) override ;
2021-12-02 06:21:36 -05:00
private :
2022-04-14 05:32:56 -04:00
bool TryApplySettingsFromConfigFiles ( const FString & ConfigEntry ) ;
2022-02-02 02:21:24 -05:00
void CreateDepotPath ( const FIoHash & PayloadId , FStringBuilderBase & OutPath ) ;
2021-12-02 06:21:36 -05:00
2022-03-01 09:05:41 -05:00
bool FindSubmissionWorkingDir ( const FString & ConfigEntry ) ;
2022-01-18 04:50:38 -05:00
/** Will display a FMessage notification to the user on the next valid engine tick to try and keep them aware of connection failures */
2023-08-23 08:22:30 -04:00
void OnConnectionError ( FText ErrorMessage ) ;
2022-03-08 11:22:45 -05:00
2022-03-09 07:43:59 -05:00
/** A source control connection owned by the backend*/
TUniquePtr < ISourceControlProvider > SCCProvider ;
2022-03-08 11:22:45 -05:00
/** The name of the current project */
FString ProjectName ;
2023-04-13 10:11:47 -04:00
/** The path (in depot format) to where the virtualized payloads are stored in source control */
FString DepotPathRoot ;
2021-12-07 03:21:51 -05:00
2022-09-21 16:29:44 -04:00
/** Address of the server to connect to */
FString ServerAddress ;
2022-08-10 08:51:05 -04:00
/** The stream containing the DepotRoot where the virtualized payloads are stored in source control */
FString ClientStream ;
2022-03-01 09:05:41 -05:00
/** The root directory from which payloads are submitted. */
FString SubmissionRootDir ;
2023-02-24 09:58:54 -05:00
/** The name to use for the p4 ignore file */
FString IgnoreFileName = TEXT ( " .p4ignore.txt " ) ;
2021-12-07 03:21:51 -05:00
/** Should we try to make the temp client partitioned or not? */
bool bUsePartitionedClient = true ;
2022-07-07 11:37:36 -04:00
/** When true, the backend will not raise a pop up notification on connection error */
bool bSuppressNotifications = false ;
/** The maximum number of files to send in a single source control operation */
2022-05-05 03:11:20 -04:00
int32 MaxBatchCount = 100 ;
2022-05-03 09:39:48 -04:00
/** A counted semaphore that will limit the number of concurrent connections that we can make */
TUniquePtr < UE : : Virtualization : : FSemaphore > ConcurrentConnectionLimit ;
2022-04-14 05:32:56 -04:00
/** The number of times to retry pulling a payload from the depot */
int32 RetryCount = 2 ;
/** The length of time (in milliseconds) to wait after each pull attempt before retrying. */
int32 RetryWaitTimeMS = 100 ;
2023-03-15 10:17:32 -04:00
/** When true we allow the revision control provider to read settings from the users local SourceControlSettings.ini file */
bool bUseLocalIniFileSettings = true ;
2023-06-20 04:26:06 -04:00
/* When true, if the initial connection to the revision control provider fails we will show a slate dialog (if possible) to the user prompting for correct settings */
bool bUseRetryConnectionDialog = false ;
2021-12-02 06:21:36 -05:00
} ;
} // namespace UE::Virtualization