New UGS are being presented a perforce exception when syncing for the first time, this seems to be because of our MaxResult limit in our perforce user groups. We use this limit to prevent unchecked queries taking out our perforce server.
Having checked the code, I cannot see a way around this so I’ve got a change to optionally restrict this sync to the last code change within N number of changes so that UGS can complete it’s first initial sync.
Steps to Reproduce
- Set perforce group to enforce MaxResults
- Open UGS
- Ensure …/.ugs/state.json has “CurrentChangeNumber” & “CurrentCodeChangeNumber” set to -1
- Attempt to sync to content code change
EpicGames.Perforce.PerforceException
HResult=0x80131500
Message=Failed: Request too large (over 2500000); see 'p4 help maxresults'. (Generic=Admin)
Source=EpicGames.Perforce
StackTrace:
at EpicGames.Perforce.PerforceResponse`1.get_Data() in D:\***\Engine\Source\Programs\Shared\EpicGames.Perforce\PerforceResponse.cs:line 149
at EpicGames.Perforce.PerforceResponseList`1.<>c.<get_Data>b__7_1(PerforceResponse`1 x) in D:\***\Engine\Source\Programs\Shared\EpicGames.Perforce\PerforceResponseList.cs:line 56
at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
at System.Linq.Enumerable.WhereEnumerableIterator`1.ToList()
at EpicGames.Perforce.PerforceResponseList`1.get_Data() in D:\***\Engine\Source\Programs\Shared\EpicGames.Perforce\PerforceResponseList.cs:line 56
at EpicGames.Perforce.PerforceConnectionExtensions.<GetChangesAsync>d__25.MoveNext() in D:\***\Engine\Source\Programs\Shared\EpicGames.Perforce\PerforceConnection.cs:line 928
at UnrealGameSync.Utility.<EnumerateChanges>d__6.MoveNext() in D:\ ***\Engine\Source\Programs\UnrealGameSync\UnrealGameSyncShared\Utility.cs:line 191
at UnrealGameSync.Utility.<EnumerateChanges>d__6.System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult(Int16 token)
at System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator`2.<MoveNextCore>d__7.MoveNext()
at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult()
at System.Linq.AsyncIteratorBase`1.<MoveNextAsync>d__8.MoveNext()
at System.Linq.AsyncIteratorBase`1.<MoveNextAsync>d__8.MoveNext()
at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()
at UnrealGameSync.Utility.<EnumerateChangeDetails>d__8.MoveNext() in D:\***\Engine\Source\Programs\UnrealGameSync\UnrealGameSyncShared\Utility.cs:line 277
at UnrealGameSync.Utility.<EnumerateChangeDetails>d__8.MoveNext() in D:\***\Engine\Source\Programs\UnrealGameSync\UnrealGameSyncShared\Utility.cs:line 339
at UnrealGameSync.Utility.<EnumerateChangeDetails>d__8.System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult(Int16 token)
This exception was originally thrown at this call stack:
EpicGames.Perforce.PerforceResponse<T>.Data.get() in PerforceResponse.cs
EpicGames.Perforce.PerforceResponseList<T>.get_Data.AnonymousMethod__7_1(EpicGames.Perforce.PerforceResponse<T>) in PerforceResponseList.cs
[External Code]
EpicGames.Perforce.PerforceResponseList<T>.Data.get() in PerforceResponseList.cs
EpicGames.Perforce.PerforceConnectionExtensions.GetChangesAsync(EpicGames.Perforce.IPerforceConnection, EpicGames.Perforce.ChangesOptions, int, EpicGames.Perforce.ChangeStatus, EpicGames.Perforce.FileSpecList, System.Threading.CancellationToken) in PerforceConnection.cs
UnrealGameSync.Utility.EnumerateChanges(EpicGames.Perforce.IPerforceConnection, System.Collections.Generic.IEnumerable<string>, int?, int?, int?, System.Threading.CancellationToken) in Utility.cs
[External Code]
UnrealGameSync.Utility.EnumerateChangeDetails(EpicGames.Perforce.IPerforceConnection, System.Collections.Generic.IAsyncEnumerable<int>, System.Collections.Generic.IEnumerable<string>, System.Threading.CancellationToken) in Utility.cs
UnrealGameSync.Utility.EnumerateChangeDetails(EpicGames.Perforce.IPerforceConnection, System.Collections.Generic.IAsyncEnumerable<int>, System.Collections.Generic.IEnumerable<string>, System.Threading.CancellationToken) in Utility.cs
Hi Jordan,
Internally we bump up the maxresults field to avoid this issue.
There are some other perforce fields you could play with to try to protect server performance, but I suspect you will hit similar limitations:
https://help.perforce.com/helix\-core/server\-apps/p4sag/2022\.2/Content/P4SAG/performance.prevention.query\_limits.html
Beyond increasing maxresults there are a few other options:
- Reducing the client view we are querying => since this would pull less results
- Adding a cap to the query i.e. your proposed fix of limiting the minChangeNumber
Your fix of adding a CodeChangeListSearchRange looks reasonable to me, let me know if this works.
Hope this helps.
That’s great news.
We have the PR tracked internally, I’ll raise it in our weekly UGS meeting to discuss potentially merging it into a release.
Hi Raymond,
Apologies for the late response, I will be sure to look at these other option and get back to you here.
Can confirm the change stops these exceptions throwing, we’ve rolled this out to a few devs internally and have had no issues.
Thanks again!