You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
==========================
MAJOR FEATURES + CHANGES
==========================
#lockdown Nick.Penwarden
Change 2879705 on 2016/02/24 by Nick.Darnell
Editor - Tweaking some comments.
#tests n/a
#rb n/a
Change 2879674 on 2016/02/24 by Nick.Darnell
Editor - The editor now supports many new methods of opening new asset editors. You can choose where tabs open with a great deal more options in Editor Preferences > Appearance > Asset Editor Open Location. This will reset the 'always open asset editors in new windows' option, it completely replaces and enchances that option.
#tests Ran the editor, tried each option and they all seem to do what I want.
#rb matt.kuhlenschmidt
Change 2879661 on 2016/02/24 by Jamie.Dale
More general fixes for dialogue waves
- The localization key now uses a hash of the speaker and target voice GUIDs to help keep them short.
- The localization key can now be user customized, and contains a placeholder format specifier for the context hash.
- The "Variations" meta-data is now called "Context".
#rb James.Hopkin
#tests Built for Windows, Linux, and PS4. Tested a loc gather and export had the correct info in it. Tested the new UI worked as expected.
Change 2879436 on 2016/02/24 by Nicholas.Davies
A few bug fixes for blocking PS4 > PC chat
#jira OR-15467 Disable Paragon chat on PS4 for users outside of the game
#RB Antony.Carter
#codereview Sam.Zamani
#TESTS PS4 whispers to and from none Paragon PC users is blocked.
Change 2878929 on 2016/02/23 by Jason.Bestimt
#ORION_DEV - Merge Main to reconcile 0.20 branch creation
#RB:none
#Tests:none
Change 2878600 on 2016/02/23 by Dmitry.Rekman
Linux: added code to identify CPU for FPSCharts (OR-14949).
#rb none
#tests Ran dedicated server on local VM and a few physical boxes.
Change 2878443 on 2016/02/23 by Marcus.Wassmer
Fix game not ticking when PS button is pressed.
#rb andrew.grant
#test golden path ps4
Change 2878361 on 2016/02/23 by Josh.Markiewicz
#UE4 - fixed bad comment
#rb none
#tests none
Change 2878205 on 2016/02/23 by Jason.Bestimt
#ORION_DEV - Merge main (0.19) at CL# 2878162
#Tests:none
#RB:none
Change 2878095 on 2016/02/23 by Josh.Markiewicz
#UE4 - added warnings to json mcp read/write failures
- removed HostAddressOverride parameter (use -uselocalips and -multihome together instead)
#rb none
#tests matchmaking golden path
Change 2878002 on 2016/02/23 by Josh.Markiewicz
#UE4 - made two party framework functions virtual
#rb none
#tests none
Change 2877998 on 2016/02/23 by Josh.Markiewicz
#Ue4 - Party interface can optionally enable/disable creating a chat room alongside the party (defaults to enabled)
#rb rob.cannaday
#tests social/team parties golden path
#codereview rob.cannaday
Change 2877822 on 2016/02/23 by Olaf.Piesche
speculative fix for OR-15710
#rb david.hill
#tests PC game
Change 2877804 on 2016/02/23 by Uriel.Doyon
Fixed ULevel::AddReferencedObjects clearing all references to static texture streaming data
#codereview robert.manuszewski
#rb marcus.wassmer
#tests played several games on PC, also doing rejoin
#jira OR-15658
Change 2877692 on 2016/02/23 by Jamie.Dale
Added commandlet to replace sound wave players in sound cues with dialogue wave players where appropriate
#rb Saul.Abreu
#tests Built for Windows, Linux, and PS4. Tested the commandlet.
Change 2877691 on 2016/02/23 by Jamie.Dale
Added commandlet to extract out the information from our character sheets and put it into the correct dialogue waves
#rb Saul.Abreu
#tests Built for Windows, Linux, and PS4. Tested the commandlet.
Change 2877690 on 2016/02/23 by Jamie.Dale
General dialogue wave fixes
[CL 2881965 by Andrew Grant in Main branch]
414 lines
14 KiB
C++
414 lines
14 KiB
C++
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "HttpPrivatePCH.h"
|
|
|
|
#include "HttpRetrySystem.h"
|
|
|
|
FHttpRetrySystem::FRequest::FRequest(
|
|
FManager& InManager,
|
|
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)
|
|
, RetryManager(InManager)
|
|
{
|
|
// if the InRetryTimeoutRelativeSecondsOverride override is being used the value cannot be negative
|
|
check(!(InRetryTimeoutRelativeSecondsOverride.bUseValue) || (InRetryTimeoutRelativeSecondsOverride.Value >= 0.0));
|
|
}
|
|
|
|
bool FHttpRetrySystem::FRequest::ProcessRequest()
|
|
{
|
|
TSharedRef<FRequest> RetryRequest = StaticCastSharedRef<FRequest>(AsShared());
|
|
|
|
HttpRequest->OnRequestProgress().BindSP(RetryRequest, &FHttpRetrySystem::FRequest::HttpOnRequestProgress);
|
|
|
|
return RetryManager.ProcessRequest(RetryRequest);
|
|
}
|
|
|
|
void FHttpRetrySystem::FRequest::CancelRequest()
|
|
{
|
|
TSharedRef<FRequest> RetryRequest = StaticCastSharedRef<FRequest>(AsShared());
|
|
|
|
RetryManager.CancelRequest(RetryRequest);
|
|
}
|
|
|
|
void FHttpRetrySystem::FRequest::HttpOnRequestProgress(FHttpRequestPtr InHttpRequest, int32 BytesSent, int32 BytesRcv)
|
|
{
|
|
OnRequestProgress().ExecuteIfBound(AsShared(), BytesSent, BytesRcv);
|
|
}
|
|
|
|
FHttpRetrySystem::FManager::FManager(const FRetryLimitCountSetting& InRetryLimitCountDefault, const FRetryTimeoutRelativeSecondsSetting& InRetryTimeoutRelativeSecondsDefault)
|
|
: RandomFailureRate(FRandomFailureRateSetting::Unused())
|
|
, RetryLimitCountDefault(InRetryLimitCountDefault)
|
|
, RetryTimeoutRelativeSecondsDefault(InRetryTimeoutRelativeSecondsDefault)
|
|
{}
|
|
|
|
TSharedRef<FHttpRetrySystem::FRequest> FHttpRetrySystem::FManager::CreateRequest(
|
|
const FRetryLimitCountSetting& InRetryLimitCountOverride,
|
|
const FRetryTimeoutRelativeSecondsSetting& InRetryTimeoutRelativeSecondsOverride,
|
|
const FRetryResponseCodes& InRetryResponseCodes)
|
|
{
|
|
return MakeShareable(new FRequest(
|
|
*this,
|
|
FHttpModule::Get().CreateRequest(),
|
|
InRetryLimitCountOverride,
|
|
InRetryTimeoutRelativeSecondsOverride,
|
|
InRetryResponseCodes
|
|
));
|
|
}
|
|
|
|
bool FHttpRetrySystem::FManager::ShouldRetry(const FHttpRetryRequestEntry& HttpRetryRequestEntry)
|
|
{
|
|
bool bResult = false;
|
|
|
|
FHttpResponsePtr Response = HttpRetryRequestEntry.Request->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.Request->GetStatus();
|
|
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.Request->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.Request->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.Request->RetryLimitCountOverride.bUseValue)
|
|
{
|
|
bShouldTestCurrentRetryCount = true;
|
|
RetryLimitCount = HttpRetryRequestEntry.Request->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.Request->RetryTimeoutRelativeSecondsOverride.bUseValue)
|
|
{
|
|
bShouldTestRetryTimeout = true;
|
|
RetryTimeoutAbsoluteSeconds += HttpRetryRequestEntry.Request->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.Request;
|
|
|
|
EHttpRequestStatus::Type RequestStatus = HttpRetryRequest->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, HttpRetryRequest->GetResponse(), bWasSuccessful);
|
|
}
|
|
|
|
if(bWasSuccessful)
|
|
{
|
|
if(CompletedCount != nullptr)
|
|
{
|
|
++(*CompletedCount);
|
|
}
|
|
}
|
|
|
|
if (bWasCompleted)
|
|
{
|
|
RequestList.RemoveAtSwap(index);
|
|
}
|
|
else
|
|
{
|
|
++index;
|
|
}
|
|
}
|
|
|
|
return bIsGreen;
|
|
}
|
|
|
|
FHttpRetrySystem::FManager::FHttpRetryRequestEntry::FHttpRetryRequestEntry(TSharedRef<FHttpRetrySystem::FRequest>& InRequest)
|
|
: bShouldCancel(false)
|
|
, CurrentRetryCount(0)
|
|
, RequestStartTimeAbsoluteSeconds(FPlatformTime::Seconds())
|
|
, Request(InRequest)
|
|
{}
|
|
|
|
bool FHttpRetrySystem::FManager::ProcessRequest(TSharedRef<FHttpRetrySystem::FRequest>& HttpRetryRequest)
|
|
{
|
|
bool bResult = HttpRetryRequest->HttpRequest->ProcessRequest();
|
|
|
|
if (bResult)
|
|
{
|
|
RequestList.Add(FHttpRetryRequestEntry(HttpRetryRequest));
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
void FHttpRetrySystem::FManager::CancelRequest(TSharedRef<FHttpRetrySystem::FRequest>& HttpRetryRequest)
|
|
{
|
|
for (int32 i = 0; i < RequestList.Num(); ++i)
|
|
{
|
|
FHttpRetryRequestEntry& EntryRef = RequestList[i];
|
|
|
|
if (EntryRef.Request == HttpRetryRequest)
|
|
{
|
|
EntryRef.bShouldCancel = true;
|
|
}
|
|
}
|
|
HttpRetryRequest->HttpRequest->CancelRequest();
|
|
}
|