You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#lockdown Nick.Penwarden ========================== MAJOR FEATURES + CHANGES ========================== Change 2845644 on 2016/01/27 by Martin.Wilson Clear marker sync flag after creating tick record, add more information to checks incase issue occurs again #Jira OR-13469 #rb Thomas.Sarkanen #tests in editor tests, bot match. Change 2845613 on 2016/01/27 by John.Pollard Latest network profiler binaries #rb none #tests run profiler Change 2845595 on 2016/01/27 by Mieszko.Zielinski Fixed pathfollowing's block detection using wrong distance when testing for blockage #UE4 #rb Lukasz.Furman #test golden path Change 2845593 on 2016/01/27 by Jeff.Farris Added support for setting and choosing filmbacks and lenses for cinematic cameras. - New CineCameraComponent and CineCameraActor classes - can define filmback and lens presets via ini file - details customizations for filmback and lens selection - added prototype set of filmbacks and lenses (primes and zooms) - Camera details customization now gracefully handles when CameraSettings category is hidden - example sequencer usage is content/developers/jeff.farris/CineCams/CineCamTestMap #rb none #tests editor Change 2845585 on 2016/01/27 by Marcus.Wassmer Don't fool with connected state if we're early outing from the OS intercepting controller events. This fixes some missing delegates. Fixes cert bug about controller disconnect screen staying up permanently #rb Cody.Haskell #test Turning off controller, turning on again. #lockdown Andrew.Grant Change 2845528 on 2016/01/27 by Max.Chen Sequencer: Fix new spawnables not immediately getting an object binding. This was resulted in a missing +Track->Animation when first creating a spawnable and duplicate transform keys. #jira UE-26084 #tests Add spawnable, +Track->Animation exists #rb none Change 2845483 on 2016/01/27 by Andrew.Rodham Sequencer: Fixed MaximizedViewport not getting cleared/restored correctly #jria UE-26016 #rb Max.Chen #tests Tested the viewports Change 2845421 on 2016/01/27 by Max.Preussner Sequencer: Implemented go-to feature #RB max.chen #TESTS Editor Change 2845407 on 2016/01/27 by Max.Preussner Sequencer: Moved SetViewRange() into ISequencer and made it public #RB max.chen #TESTS none Change 2845404 on 2016/01/27 by Andrew.Rodham Sequencer: Fixed cinematic viewport not updating when dragging transport range #jira UE-26003 #rb Max.Chen #tests Scrubbed the timeline Change 2845396 on 2016/01/27 by David.Nikdel #OSS #Purchase #Store #PS4 - Minor log cleanup #RB: none #TESTS: compiles Change 2845375 on 2016/01/27 by Max.Chen Sequencer: Implement cinematic shot track thumbnails. #jira UE-25125 #tests Rebuild the trailer with the cinematic shot track #rb none Change 2845359 on 2016/01/27 by Marcus.Wassmer Downgrade some checks to ensures. #rb none #test ps4 Change 2845347 on 2016/01/27 by Nicholas.Davies Remove unused EditorStyle dependency from Social. It is not being used, and causes issues for the engine team. #RB Antony.Carter #TESTS n/a #codereview Robert.Manuszewski Change 2845227 on 2016/01/27 by Robert.Manuszewski Adding flags to create callstack map files when building Arxan protection #rb none #tests Built arxan exe Change 2844871 on 2016/01/26 by Andrew.Grant Prevent enums from being regenerated while cooking (prevents false-positive warning about FText's being regenerated) #rb none #tests ran editor [CL 2847722 by Andrew Grant in Main branch]
386 lines
13 KiB
C++
386 lines
13 KiB
C++
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "HttpPrivatePCH.h"
|
|
|
|
#include "HttpRetrySystem.h"
|
|
|
|
FHttpRetrySystem::FRequest::FRequest(
|
|
const TSharedRef<IHttpRequest>& HttpRequest,
|
|
const FHttpRetrySystem::FRetryLimitCountSetting& InRetryLimitCountOverride,
|
|
const FHttpRetrySystem::FRetryTimeoutRelativeSecondsSetting& InRetryTimeoutRelativeSecondsOverride,
|
|
const FHttpRetrySystem::FRetryResponseCodes& InRetryResponseCodes
|
|
)
|
|
: FHttpRequestAdapterBase(HttpRequest)
|
|
, Status(FHttpRetrySystem::FRequest::EStatus::NotStarted)
|
|
, RetryLimitCountOverride(InRetryLimitCountOverride)
|
|
, RetryTimeoutRelativeSecondsOverride(InRetryTimeoutRelativeSecondsOverride)
|
|
, RetryResponseCodes(InRetryResponseCodes)
|
|
{
|
|
// if the InRetryTimeoutRelativeSecondsOverride override is being used the value cannot be negative
|
|
check(!(InRetryTimeoutRelativeSecondsOverride.bUseValue) || (InRetryTimeoutRelativeSecondsOverride.Value >= 0.0));
|
|
}
|
|
|
|
FHttpRetrySystem::FManager::FManager(const FRetryLimitCountSetting& InRetryLimitCountDefault, const FRetryTimeoutRelativeSecondsSetting& InRetryTimeoutRelativeSecondsDefault)
|
|
: RandomFailureRate(FRandomFailureRateSetting::Unused())
|
|
, RetryLimitCountDefault(InRetryLimitCountDefault)
|
|
, RetryTimeoutRelativeSecondsDefault(InRetryTimeoutRelativeSecondsDefault)
|
|
{}
|
|
|
|
bool FHttpRetrySystem::FManager::ShouldRetry(const FHttpRetryRequestEntry& HttpRetryRequestEntry)
|
|
{
|
|
bool bResult = false;
|
|
|
|
FHttpResponsePtr Response = HttpRetryRequestEntry.HttpRequest->GetResponse();
|
|
// invalid response means connection or network error but we need to know which one
|
|
if (!Response.IsValid())
|
|
{
|
|
// ONLY retry bad responses if they are connection errors (NOT protocol errors or unknown) otherwise request may be sent (and processed!) twice
|
|
EHttpRequestStatus::Type Status = HttpRetryRequestEntry.HttpRequest->GetRequestStatus();
|
|
if (Status == EHttpRequestStatus::Failed_ConnectionError)
|
|
{
|
|
bResult = true;
|
|
}
|
|
else if (Status == EHttpRequestStatus::Failed)
|
|
{
|
|
// we will also allow retry for GET and HEAD requests even if they may duplicate on the server
|
|
FString Verb = HttpRetryRequestEntry.HttpRequest->GetVerb();
|
|
if (Verb == TEXT("GET") || Verb == TEXT("HEAD"))
|
|
{
|
|
bResult = true;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// this may be a successful response with one of the explicitly listed response codes we want to retry on
|
|
if (HttpRetryRequestEntry.HttpRequest->RetryResponseCodes.Contains(Response->GetResponseCode()))
|
|
{
|
|
bResult = true;
|
|
}
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
bool FHttpRetrySystem::FManager::CanRetry(const FHttpRetryRequestEntry& HttpRetryRequestEntry)
|
|
{
|
|
bool bResult = false;
|
|
|
|
bool bShouldTestCurrentRetryCount = false;
|
|
double RetryLimitCount = 0;
|
|
if (HttpRetryRequestEntry.HttpRequest->RetryLimitCountOverride.bUseValue)
|
|
{
|
|
bShouldTestCurrentRetryCount = true;
|
|
RetryLimitCount = HttpRetryRequestEntry.HttpRequest->RetryLimitCountOverride.Value;
|
|
}
|
|
else if (RetryLimitCountDefault.bUseValue)
|
|
{
|
|
bShouldTestCurrentRetryCount = true;
|
|
RetryLimitCount = RetryLimitCountDefault.Value;
|
|
}
|
|
|
|
if (bShouldTestCurrentRetryCount)
|
|
{
|
|
if (HttpRetryRequestEntry.CurrentRetryCount < RetryLimitCount)
|
|
{
|
|
bResult = true;
|
|
}
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
bool FHttpRetrySystem::FManager::HasTimedOut(const FHttpRetryRequestEntry& HttpRetryRequestEntry, const double NowAbsoluteSeconds)
|
|
{
|
|
bool bResult = false;
|
|
|
|
bool bShouldTestRetryTimeout = false;
|
|
double RetryTimeoutAbsoluteSeconds = HttpRetryRequestEntry.RequestStartTimeAbsoluteSeconds;
|
|
if (HttpRetryRequestEntry.HttpRequest->RetryTimeoutRelativeSecondsOverride.bUseValue)
|
|
{
|
|
bShouldTestRetryTimeout = true;
|
|
RetryTimeoutAbsoluteSeconds += HttpRetryRequestEntry.HttpRequest->RetryTimeoutRelativeSecondsOverride.Value;
|
|
}
|
|
else if (RetryTimeoutRelativeSecondsDefault.bUseValue)
|
|
{
|
|
bShouldTestRetryTimeout = true;
|
|
RetryTimeoutAbsoluteSeconds += RetryTimeoutRelativeSecondsDefault.Value;
|
|
}
|
|
|
|
if (bShouldTestRetryTimeout)
|
|
{
|
|
if (NowAbsoluteSeconds >= RetryTimeoutAbsoluteSeconds)
|
|
{
|
|
bResult = true;
|
|
}
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
float FHttpRetrySystem::FManager::GetLockoutPeriodSeconds(const FHttpRetryRequestEntry& HttpRetryRequestEntry)
|
|
{
|
|
float lockoutTime = 0.0f;
|
|
|
|
if(HttpRetryRequestEntry.CurrentRetryCount >= 1)
|
|
{
|
|
lockoutTime = 5.0f + 5.0f * ((HttpRetryRequestEntry.CurrentRetryCount - 1) >> 1);
|
|
lockoutTime = lockoutTime > 30.0f ? 30.0f : lockoutTime;
|
|
}
|
|
|
|
return lockoutTime;
|
|
}
|
|
|
|
static FRandomStream temp(4435261);
|
|
|
|
bool FHttpRetrySystem::FManager::Update(uint32* FileCount, uint32* FailingCount, uint32* FailedCount, uint32* CompletedCount)
|
|
{
|
|
bool bIsGreen = true;
|
|
|
|
if (FileCount != nullptr)
|
|
{
|
|
*FileCount = RequestList.Num();
|
|
}
|
|
|
|
const double NowAbsoluteSeconds = FPlatformTime::Seconds();
|
|
|
|
// Basic algorithm
|
|
// for each managed item
|
|
// if the item hasn't timed out
|
|
// if the item's retry state is NotStarted
|
|
// if the item's request's state is not NotStarted
|
|
// move the item's retry state to Processing
|
|
// endif
|
|
// endif
|
|
// if the item's retry state is Processing
|
|
// if the item's request's state is Failed
|
|
// flag return code to false
|
|
// if the item can be retried
|
|
// increment FailingCount if applicable
|
|
// retry the item's request
|
|
// increment the item's retry count
|
|
// else
|
|
// increment FailedCount if applicable
|
|
// set the item's retry state to FailedRetry
|
|
// endif
|
|
// else if the item's request's state is Succeeded
|
|
// endif
|
|
// endif
|
|
// else
|
|
// flag return code to false
|
|
// set the item's retry state to FailedTimeout
|
|
// increment FailedCount if applicable
|
|
// endif
|
|
// if the item's retry state is FailedRetry
|
|
// do stuff
|
|
// endif
|
|
// if the item's retry state is FailedTimeout
|
|
// do stuff
|
|
// endif
|
|
// if the item's retry state is Succeeded
|
|
// do stuff
|
|
// endif
|
|
// endfor
|
|
|
|
int32 index = 0;
|
|
while (index < RequestList.Num())
|
|
{
|
|
FHttpRetryRequestEntry& HttpRetryRequestEntry = RequestList[index];
|
|
TSharedRef<FHttpRetrySystem::FRequest>& HttpRetryRequest = HttpRetryRequestEntry.HttpRequest;
|
|
|
|
EHttpRequestStatus::Type RequestStatus = HttpRetryRequest->HttpRequest->GetStatus();
|
|
|
|
if (!HasTimedOut(HttpRetryRequestEntry, NowAbsoluteSeconds))
|
|
{
|
|
if (HttpRetryRequest->Status == FHttpRetrySystem::FRequest::EStatus::NotStarted)
|
|
{
|
|
if (RequestStatus != EHttpRequestStatus::NotStarted)
|
|
{
|
|
HttpRetryRequest->Status = FHttpRetrySystem::FRequest::EStatus::Processing;
|
|
}
|
|
}
|
|
|
|
if (HttpRetryRequest->Status == FHttpRetrySystem::FRequest::EStatus::Processing)
|
|
{
|
|
bool forceFail = false;
|
|
|
|
// Code to simulate request failure
|
|
if (RequestStatus == EHttpRequestStatus::Succeeded && RandomFailureRate.bUseValue)
|
|
{
|
|
float random = temp.GetFraction();
|
|
if (random < RandomFailureRate.Value)
|
|
{
|
|
forceFail = true;
|
|
}
|
|
}
|
|
|
|
// Save these for failure case retry checks if we hit a completion state
|
|
bool bShouldRetry = false;
|
|
bool bCanRetry = false;
|
|
if (RequestStatus == EHttpRequestStatus::Failed || RequestStatus == EHttpRequestStatus::Failed_ConnectionError || RequestStatus == EHttpRequestStatus::Succeeded)
|
|
{
|
|
bShouldRetry = ShouldRetry(HttpRetryRequestEntry);
|
|
bCanRetry = CanRetry(HttpRetryRequestEntry);
|
|
}
|
|
|
|
if (RequestStatus == EHttpRequestStatus::Failed || RequestStatus == EHttpRequestStatus::Failed_ConnectionError || forceFail || (bShouldRetry && bCanRetry))
|
|
{
|
|
bIsGreen = false;
|
|
if(HttpRetryRequestEntry.bShouldCancel == false)
|
|
{
|
|
if (forceFail || (bShouldRetry && bCanRetry))
|
|
{
|
|
float lockoutPeriod = GetLockoutPeriodSeconds(HttpRetryRequestEntry);
|
|
|
|
if(lockoutPeriod > 0.0f)
|
|
{
|
|
UE_LOG(LogHttp, Warning, TEXT("Lockout of %fs on %s"), lockoutPeriod, *(HttpRetryRequest->GetURL()));
|
|
}
|
|
|
|
HttpRetryRequestEntry.LockoutEndTimeAbsoluteSeconds = NowAbsoluteSeconds + lockoutPeriod;
|
|
HttpRetryRequest->Status = FHttpRetrySystem::FRequest::EStatus::ProcessingLockout;
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LogHttp, Warning, TEXT("Retry exhausted on %s"), *(HttpRetryRequest->GetURL()));
|
|
if (FailedCount != nullptr)
|
|
{
|
|
++(*FailedCount);
|
|
}
|
|
HttpRetryRequest->Status = FHttpRetrySystem::FRequest::EStatus::FailedRetry;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LogHttp, Warning, TEXT("Request cancelled on %s"), *(HttpRetryRequest->GetURL()));
|
|
HttpRetryRequest->Status = FHttpRetrySystem::FRequest::EStatus::Cancelled;
|
|
}
|
|
}
|
|
else if (RequestStatus == EHttpRequestStatus::Succeeded)
|
|
{
|
|
if (HttpRetryRequestEntry.CurrentRetryCount > 0)
|
|
{
|
|
UE_LOG(LogHttp, Warning, TEXT("Success on %s"), *(HttpRetryRequest->GetURL()));
|
|
}
|
|
|
|
if (CompletedCount != nullptr)
|
|
{
|
|
++(*CompletedCount);
|
|
}
|
|
|
|
HttpRetryRequest->Status = FHttpRetrySystem::FRequest::EStatus::Succeeded;
|
|
}
|
|
}
|
|
|
|
if (HttpRetryRequest->Status == FHttpRetrySystem::FRequest::EStatus::ProcessingLockout)
|
|
{
|
|
if (NowAbsoluteSeconds >= HttpRetryRequestEntry.LockoutEndTimeAbsoluteSeconds)
|
|
{
|
|
// if this fails the HttpRequest's state will be failed which will cause the retry logic to kick(as expected)
|
|
bool success = HttpRetryRequest->HttpRequest->ProcessRequest();
|
|
if (success)
|
|
{
|
|
UE_LOG(LogHttp, Warning, TEXT("Retry %d on %s"), HttpRetryRequestEntry.CurrentRetryCount + 1, *(HttpRetryRequest->GetURL()));
|
|
|
|
++HttpRetryRequestEntry.CurrentRetryCount;
|
|
HttpRetryRequest->Status = FRequest::EStatus::Processing;
|
|
}
|
|
}
|
|
|
|
if (FailingCount != nullptr)
|
|
{
|
|
++(*FailingCount);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LogHttp, Warning, TEXT("Timeout on retry %d: %s"), HttpRetryRequestEntry.CurrentRetryCount + 1, *(HttpRetryRequest->GetURL()));
|
|
bIsGreen = false;
|
|
HttpRetryRequest->Status = FHttpRetrySystem::FRequest::EStatus::FailedTimeout;
|
|
if (FailedCount != nullptr)
|
|
{
|
|
++(*FailedCount);
|
|
}
|
|
}
|
|
|
|
bool bWasCompleted = false;
|
|
bool bWasSuccessful = false;
|
|
|
|
if (HttpRetryRequest->Status == FHttpRetrySystem::FRequest::EStatus::Cancelled ||
|
|
HttpRetryRequest->Status == FHttpRetrySystem::FRequest::EStatus::FailedRetry ||
|
|
HttpRetryRequest->Status == FHttpRetrySystem::FRequest::EStatus::FailedTimeout ||
|
|
HttpRetryRequest->Status == FHttpRetrySystem::FRequest::EStatus::Succeeded)
|
|
{
|
|
bWasCompleted = true;
|
|
bWasSuccessful = HttpRetryRequest->Status == FHttpRetrySystem::FRequest::EStatus::Succeeded;
|
|
}
|
|
|
|
if (bWasCompleted)
|
|
{
|
|
HttpRetryRequest->OnProcessRequestComplete().ExecuteIfBound(HttpRetryRequest, bWasSuccessful);
|
|
}
|
|
|
|
if(bWasSuccessful)
|
|
{
|
|
if(CompletedCount != nullptr)
|
|
{
|
|
++(*CompletedCount);
|
|
}
|
|
}
|
|
|
|
if (bWasCompleted)
|
|
{
|
|
RequestList.RemoveAtSwap(index);
|
|
}
|
|
else
|
|
{
|
|
++index;
|
|
}
|
|
}
|
|
|
|
return bIsGreen;
|
|
}
|
|
|
|
FHttpRetrySystem::FManager::FHttpRetryRequestEntry::FHttpRetryRequestEntry(TSharedRef<FHttpRetrySystem::FRequest>& InHttpRequest)
|
|
: bShouldCancel(false)
|
|
, CurrentRetryCount(0)
|
|
, RequestStartTimeAbsoluteSeconds(FPlatformTime::Seconds())
|
|
, HttpRequest(InHttpRequest)
|
|
{}
|
|
|
|
bool FHttpRetrySystem::FManager::ProcessRequest(TSharedRef<FHttpRetrySystem::FRequest>& HttpRequest)
|
|
{
|
|
bool bResult = HttpRequest->ProcessRequest();
|
|
|
|
if (bResult)
|
|
{
|
|
RequestList.Add(FHttpRetryRequestEntry(HttpRequest));
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
void FHttpRetrySystem::FManager::CancelRequest(TSharedRef<FHttpRetrySystem::FRequest>& HttpRequest)
|
|
{
|
|
for (int32 i = 0; i < RequestList.Num(); ++i)
|
|
{
|
|
FHttpRetryRequestEntry& EntryRef = RequestList[i];
|
|
|
|
if(EntryRef.HttpRequest == HttpRequest)
|
|
{
|
|
EntryRef.bShouldCancel = true;
|
|
}
|
|
}
|
|
HttpRequest->CancelRequest();
|
|
|
|
/*
|
|
if (bResult)
|
|
{
|
|
RequestList.Add(FHttpRetryRequestEntry(HttpRequest));
|
|
}
|
|
|
|
return bResult;
|
|
*/
|
|
}
|