Files
UnrealEngineUWP/Engine/Source/Runtime/Online/BackgroundHTTP/Private/BackgroundHttpRequestImpl.cpp
thomas ross b6ec1d7d18 BackgroundHttp Improvements:
- Added priority system for Background HTTP downloads.
- Fixed bug where dropping internet connection mid-download would trigger an ensure and try to re-activate all possible download tasks on iOS at once.
- Fixed issue where we were immediately calling the NSURLSession Background completion handler instead of waiting for threads to finish their work. Could lead to scenarios where we weren't finishing re-queuing failed tasks in the background if many failed.
[CODEREVIEW] [at]Justin.Marcus, [at]Daniel.Lamb
#tests iOS Client, Android Client
#rb none


#ROBOMERGE-SOURCE: CL 10149845 via CL 10150034 via CL 10150114
#ROBOMERGE-BOT: (v587-10111126)

[CL 10150178 by thomas ross in Main branch]
2019-11-13 14:31:30 -05:00

152 lines
5.3 KiB
C++

// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#include "BackgroundHttpRequestImpl.h"
#include "BackgroundHttpModule.h"
#include "Interfaces/IBackgroundHttpResponse.h"
DEFINE_LOG_CATEGORY(LogBackgroundHttpRequest);
FBackgroundHttpRequestImpl::FBackgroundHttpRequestImpl()
: DownloadCompleteNotificationObject(nullptr)
, Response(nullptr)
, URLList()
, RequestID()
, NumberOfTotalRetries(0)
, RequestPriority(EBackgroundHTTPPriority::Normal)
, HttpRequestCompleteDelegate()
, HttpProgressUpdateDelegate()
{
}
bool FBackgroundHttpRequestImpl::ProcessRequest()
{
UE_LOG(LogBackgroundHttpRequest, Display, TEXT("Processing Request - RequestID:%s"), *GetRequestID());
FBackgroundHttpModule::Get().GetBackgroundHttpManager()->AddRequest(SharedThis(this));
return true;
}
void FBackgroundHttpRequestImpl::CancelRequest()
{
UE_LOG(LogBackgroundHttpRequest, Display, TEXT("Cancelling Request - RequestID:%s"), *GetRequestID());
FBackgroundHttpModule::Get().GetBackgroundHttpManager()->RemoveRequest(SharedThis(this));
}
void FBackgroundHttpRequestImpl::PauseRequest()
{
//for now a pause is just wrapping a cancel in the general case
UE_LOG(LogBackgroundHttpRequest, Display, TEXT("Pausing Request (through cancel) - RequestID:%s"), *GetRequestID());
CancelRequest();
}
void FBackgroundHttpRequestImpl::ResumeRequest()
{
//for now a resume is just wrapping a restart in the general case
UE_LOG(LogBackgroundHttpRequest, Display, TEXT("Pausing Request (through restart) - RequestID:%s"), *GetRequestID());
ProcessRequest();
}
void FBackgroundHttpRequestImpl::OnBackgroundDownloadComplete()
{
FBackgroundHttpModule::Get().GetBackgroundHttpManager()->RemoveRequest(SharedThis(this));
//Determine if this was a success or not
FBackgroundHttpResponsePtr SetResponse = GetResponse();
const bool bWasSuccess = SetResponse.IsValid() ? EHttpResponseCodes::IsOk(SetResponse->GetResponseCode()) : false;
UE_LOG(LogBackgroundHttpRequest, Display, TEXT("Download Complete - RequestID:%s | bWasSuccess:%d "), *GetRequestID(), (int)(bWasSuccess));
//First, send a delegate out for this request completing
OnProcessRequestComplete().ExecuteIfBound(SharedThis(this), bWasSuccess);
//Second notify our download complete notification of the success/failure of this request. Then remove our reference
//so a notification will send without having to delete this request. Do this after Complete Delegate so we can ensure
//whatever kicked this off doesn't want to react to this download complete before we send this notification (IE: Kick off another download
//using the same NotificationObject, etc.)
NotifyNotificationObjectOfComplete(bWasSuccess);
}
void FBackgroundHttpRequestImpl::NotifyNotificationObjectOfComplete(bool bWasSuccess)
{
if (DownloadCompleteNotificationObject.IsValid())
{
const int32 SharedRefCount = DownloadCompleteNotificationObject.GetSharedReferenceCount();
UE_LOG(LogBackgroundHttpRequest, Display, TEXT("Removing Reference to DownloadCompleteNotificationObject - bWasSuccess:%d | CurrentSharedRefCount:%d"), (int)(bWasSuccess), SharedRefCount);
DownloadCompleteNotificationObject->NotifyOfDownloadResult(bWasSuccess);
DownloadCompleteNotificationObject.Reset();
}
}
void FBackgroundHttpRequestImpl::SetURLAsList(const TArray<FString>& URLs, int NumRetriesIn)
{
NumberOfTotalRetries = NumRetriesIn;
for (const FString& URL : URLs)
{
URLList.Add(URL);
}
}
const TArray<FString>& FBackgroundHttpRequestImpl::GetURLList() const
{
return URLList;
}
void FBackgroundHttpRequestImpl::SetCompleteNotification(FBackgroundHttpNotificationObjectPtr DownloadCompleteNotificationObjectIn)
{
DownloadCompleteNotificationObject = DownloadCompleteNotificationObjectIn;
}
void FBackgroundHttpRequestImpl::CompleteWithExistingResponseData(FBackgroundHttpResponsePtr BackgroundResponse)
{
Response = BackgroundResponse;
const bool bHasValidResponse = Response.IsValid();
UE_LOG(LogBackgroundHttpRequest, Display, TEXT("Completing Download With Existing Response Data - RequestID:%s | bHasValidResponse:%d"), *GetRequestID(), (int)(bHasValidResponse));
OnBackgroundDownloadComplete();
}
FBackgroundHttpRequestCompleteDelegate& FBackgroundHttpRequestImpl::OnProcessRequestComplete()
{
return HttpRequestCompleteDelegate;
}
FBackgroundHttpProgressUpdateDelegate& FBackgroundHttpRequestImpl::OnProgressUpdated()
{
return HttpProgressUpdateDelegate;
}
const FBackgroundHttpResponsePtr FBackgroundHttpRequestImpl::GetResponse() const
{
return Response;
}
const FString& FBackgroundHttpRequestImpl::GetRequestID() const
{
return RequestID;
}
void FBackgroundHttpRequestImpl::SetRequestID(const FString& NewRequestID)
{
RequestID = NewRequestID;
}
bool FBackgroundHttpRequestImpl::HandleDelayedProcess()
{
//By default we don't provide an implementation for this. If this is called, it should be overriden by the platform specific
//BackgroundHttpRequest if the platform expects to make use of this.
return ensureAlwaysMsgf(false, TEXT("Platform expects an implementation of HandleDelayedProcess on the BackgroundHttpRequest, but none found!"));
}
EBackgroundHTTPPriority FBackgroundHttpRequestImpl::GetRequestPriority() const
{
return RequestPriority;
}
void FBackgroundHttpRequestImpl::SetRequestPriority(EBackgroundHTTPPriority NewPriority)
{
RequestPriority = NewPriority;
}