Files
DTFluxAPI/Source/DTFluxNetwork/Private/DTFluxQueuedManager.cpp

671 lines
18 KiB
C++
Raw Permalink Normal View History

2025-07-11 19:04:37 +02:00
// ================================================================================================
// DTFluxRequestManager.cpp - Implémentation du gestionnaire de requêtes
// ================================================================================================
#include "DTFluxQueuedManager.h"
2025-07-11 19:04:37 +02:00
#include "DTFluxAsyncParser.h"
#include "DTFluxNetworkModule.h"
2025-07-11 19:04:37 +02:00
#include "Struct/DTFluxServerResponseStruct.h"
#include "Struct/DTFluxRequestStructs.h"
#include "JsonObjectConverter.h"
2025-07-11 19:04:37 +02:00
bool FDTFluxTrackedRequest::HasTimedOut() const
{
if (State != EDTFluxRequestState::Pending && State != EDTFluxRequestState::Sent)
return false;
return (FDateTime::Now() - CreatedAt).GetTotalSeconds() > Config.TimeoutSeconds;
}
bool FDTFluxTrackedRequest::CanRetry() const
{
return CurrentRetries < Config.MaxRetries &&
(State == EDTFluxRequestState::Failed || State == EDTFluxRequestState::TimedOut);
}
float FDTFluxTrackedRequest::GetRetryDelay() const
{
return FMath::Pow(Config.RetryBackoffMultiplier, CurrentRetries);
}
bool FDTFluxTrackedRequest::Matches(EDTFluxApiDataType InType, int32 InContestId, int32 InStageId,
int32 InSplitId) const
{
return RequestType == InType && ContestId == InContestId && StageId == InStageId && SplitId == InSplitId;
}
2025-07-11 19:04:37 +02:00
void FDTFluxTrackedRequest::SetRawResponse(const FString& RawData)
{
RawResponseData = RawData;
ParsedResponse.Reset();
bIsResponseParsed = false;
}
FString FDTFluxTrackedRequest::Serialize() const
{
FString JSONString;
switch (RequestType)
{
2025-07-11 19:04:37 +02:00
case EDTFluxApiDataType::RaceData:
{
FDTFluxRaceDataRequest RaceData;
FJsonObjectConverter::UStructToJsonObjectString(RaceData, JSONString);
break;
}
2025-07-11 19:04:37 +02:00
case EDTFluxApiDataType::TeamList:
{
const FDTFluxTeamListRequest TeamList;
FJsonObjectConverter::UStructToJsonObjectString(TeamList, JSONString);
break;
}
2025-07-11 19:04:37 +02:00
case EDTFluxApiDataType::ContestRanking:
{
FDTFluxContestRankingRequest ContestRanking(ContestId);
FJsonObjectConverter::UStructToJsonObjectString(ContestRanking, JSONString);
break;
}
2025-07-11 19:04:37 +02:00
case EDTFluxApiDataType::StageRanking:
{
FDTFluxStageRankingRequest StageRanking(ContestId, StageId);
FJsonObjectConverter::UStructToJsonObjectString(StageRanking, JSONString);
break;
}
2025-07-11 19:04:37 +02:00
case EDTFluxApiDataType::SplitRanking:
{
FDTFluxSplitRankingRequest SplitRanking(ContestId, StageId, SplitId);
FJsonObjectConverter::UStructToJsonObjectString(SplitRanking, JSONString);
break;
}
default:
JSONString = "";
break;
}
return JSONString;
}
2025-07-11 19:04:37 +02:00
FDTFluxQueuedRequestManager::FDTFluxQueuedRequestManager()
{
2025-07-11 19:04:37 +02:00
AsyncParser = MakeUnique<FDTFluxAsyncParser>();
UE_LOG(logDTFluxNetwork, Verbose, TEXT("RequestManager created"));
}
2025-07-11 19:04:37 +02:00
FDTFluxQueuedRequestManager::~FDTFluxQueuedRequestManager()
{
2025-07-11 19:04:37 +02:00
Shutdown();
UE_LOG(logDTFluxNetwork, Verbose, TEXT("RequestManager destroyed"));
}
2025-07-11 19:04:37 +02:00
void FDTFluxQueuedRequestManager::Initialize(const FDTFluxRequestConfig& InDefaultConfig)
{
2025-07-11 19:04:37 +02:00
if (bIsInitialized.load())
{
2025-07-11 19:04:37 +02:00
UE_LOG(logDTFluxNetwork, Warning, TEXT("RequestManager already initialized"));
return;
}
2025-07-11 19:04:37 +02:00
DefaultConfig = InDefaultConfig;
bIsInitialized.store(true);
UE_LOG(logDTFluxNetwork, Log, TEXT("RequestManager initialized with timeout=%.1fs"),
DefaultConfig.TimeoutSeconds);
}
2025-07-11 19:04:37 +02:00
void FDTFluxQueuedRequestManager::Shutdown()
{
2025-07-11 19:04:37 +02:00
if (!bIsInitialized.load())
return;
2025-07-11 19:04:37 +02:00
bIsInitialized.store(false);
// Nettoyer toutes les données
{
FScopeLock RequestsLock_Local(&RequestsLock);
FScopeLock CallbacksLock_Local(&CallbacksLock);
2025-07-11 19:04:37 +02:00
AllRequests.Empty();
SuccessCallbacks.Empty();
ErrorCallbacks.Empty();
}
2025-07-11 19:04:37 +02:00
UE_LOG(logDTFluxNetwork, Log, TEXT("RequestManager shutdown"));
}
2025-07-11 19:04:37 +02:00
FGuid FDTFluxQueuedRequestManager::CreateTrackedRequest(
EDTFluxApiDataType RequestType,
int32 ContestId,
int32 StageId,
int32 SplitId,
const FDTFluxRequestConfig& CustomConfig)
{
2025-07-11 19:04:37 +02:00
if (!bIsInitialized.load())
{
2025-07-11 19:04:37 +02:00
UE_LOG(logDTFluxNetwork, Error, TEXT("RequestManager not initialized"));
return FGuid();
}
// Create new request
2025-07-11 19:04:37 +02:00
auto NewRequest = MakeShared<FDTFluxTrackedRequest>();
NewRequest->RequestType = RequestType;
NewRequest->ContestId = ContestId;
NewRequest->StageId = StageId;
NewRequest->SplitId = SplitId;
NewRequest->Config = (CustomConfig.TimeoutSeconds > 0) ? CustomConfig : DefaultConfig;
FGuid RequestId = NewRequest->RequestId;
{
2025-07-11 19:04:37 +02:00
FScopeLock Lock(&RequestsLock);
AllRequests.Add(RequestId, NewRequest);
TotalRequests++;
}
2025-07-11 19:04:37 +02:00
UE_LOG(logDTFluxNetwork, Log, TEXT("Created tracked request %s: Type=%s, Contest=%d, Stage=%d, Split=%d"),
*RequestId.ToString(), *UEnum::GetValueAsString(RequestType), ContestId, StageId, SplitId);
return RequestId;
}
FGuid FDTFluxQueuedRequestManager::CreateTrackedRequestWithCallbacks(
EDTFluxApiDataType RequestType,
int32 ContestId,
int32 StageId,
int32 SplitId,
FOnDTFluxRequestSuccess OnSuccess,
FOnDTFluxRequestError OnError,
const FDTFluxRequestConfig& CustomConfig)
{
FGuid RequestId = CreateTrackedRequest(RequestType, ContestId, StageId, SplitId, CustomConfig);
if (RequestId.IsValid())
{
2025-07-11 19:04:37 +02:00
FScopeLock Lock(&CallbacksLock);
if (OnSuccess.IsBound())
{
SuccessCallbacks.Add(RequestId, OnSuccess);
}
if (OnError.IsBound())
{
ErrorCallbacks.Add(RequestId, OnError);
}
}
2025-07-11 19:04:37 +02:00
return RequestId;
}
2025-07-11 19:04:37 +02:00
bool FDTFluxQueuedRequestManager::MarkRequestAsSent(const FGuid& RequestId)
{
2025-07-11 19:04:37 +02:00
FScopeLock Lock(&RequestsLock);
2025-07-11 19:04:37 +02:00
if (TSharedPtr<FDTFluxTrackedRequest>* RequestPtr = AllRequests.Find(RequestId))
{
2025-07-11 19:04:37 +02:00
TSharedPtr<FDTFluxTrackedRequest> Request = *RequestPtr;
Request->SentAt = FDateTime::Now();
Request->LastAttemptTime = FDateTime::Now();
ChangeRequestState(Request, EDTFluxRequestState::Sent);
return true;
}
2025-07-11 19:04:37 +02:00
return false;
}
2025-07-11 19:04:37 +02:00
bool FDTFluxQueuedRequestManager::CompleteRequest(const FGuid& RequestId, const FString& RawResponseData,
bool bUseAsyncParsing)
{
UE_LOG(logDTFluxNetwork, Log, TEXT("FDTFluxQueuedRequestManager::CompleteRequest() %s"), *RequestId.ToString());
2025-07-11 19:04:37 +02:00
TSharedPtr<FDTFluxTrackedRequest> Request;
{
FScopeLock Lock(&RequestsLock);
if (TSharedPtr<FDTFluxTrackedRequest>* RequestPtr = AllRequests.Find(RequestId))
{
2025-07-11 19:04:37 +02:00
Request = *RequestPtr;
}
}
2025-07-11 19:04:37 +02:00
if (!Request.IsValid())
{
2025-07-11 19:04:37 +02:00
UE_LOG(logDTFluxNetwork, Warning, TEXT("Request %s not found"), *RequestId.ToString());
return false;
}
// Store RawResponse
2025-07-11 19:04:37 +02:00
Request->SetRawResponse(RawResponseData);
Request->CompletedAt = FDateTime::Now();
UE_LOG(logDTFluxNetwork, Log, TEXT("Request %s completed at %s"), *RequestId.ToString(),
*Request->CompletedAt.ToString());
// Decide to parse based upon config
2025-07-11 19:04:37 +02:00
bool bHasCallbacks = false;
{
FScopeLock Lock(&CallbacksLock);
bHasCallbacks = SuccessCallbacks.Contains(RequestId) || ErrorCallbacks.Contains(RequestId);
}
if (bHasCallbacks && bUseAsyncParsing && !RawResponseData.IsEmpty())
{
UE_LOG(logDTFluxNetwork, Log,
TEXT("Request %s [bHasCallbacks=%s], [bUseAsyncParsing=%s], [bIsRawResponseEmpty=%s]"),
*RequestId.ToString(),
bHasCallbacks ? TEXT("true") : TEXT("false"), bUseAsyncParsing ? TEXT("true") : TEXT("false"),
RawResponseData.IsEmpty() ? TEXT("true") : TEXT("false"));
// Async parsing for Cb
2025-07-11 19:04:37 +02:00
FOnParsingCompleted OnCompleted = FOnParsingCompleted::CreateRaw(
this, &FDTFluxQueuedRequestManager::OnParsingCompleted
);
FOnParsingFailed OnFailed = FOnParsingFailed::CreateRaw(
this, &FDTFluxQueuedRequestManager::OnParsingFailed
);
// Maybe send to parser in another place
2025-07-11 19:04:37 +02:00
AsyncParser->ParseResponseAsync(RequestId, RawResponseData, OnCompleted, OnFailed);
UE_LOG(logDTFluxNetwork, Verbose, TEXT("Started async parsing for request %s"), *RequestId.ToString());
return true;
}
2025-07-11 19:04:37 +02:00
else
{
UE_LOG(logDTFluxNetwork, Warning, TEXT("request %s completed without sync"), *RequestId.ToString());
2025-07-11 19:04:37 +02:00
// Compléter immédiatement sans parsing ou avec parsing sync
EDTFluxRequestState NewState = EDTFluxRequestState::Completed;
2025-07-11 19:04:37 +02:00
ChangeRequestState(Request, NewState);
// Déclencher les callbacks avec les données brutes
TriggerCallbacks(*Request);
CleanupCallbacks(RequestId);
return true;
}
}
/**
* @todo Check protocol errors ???
* @param RequestId
* @param ErrorMessage
* @return
*/
2025-07-11 19:04:37 +02:00
bool FDTFluxQueuedRequestManager::FailRequest(const FGuid& RequestId, const FString& ErrorMessage)
{
2025-07-11 19:04:37 +02:00
TSharedPtr<FDTFluxTrackedRequest> Request;
{
FScopeLock Lock(&RequestsLock);
if (TSharedPtr<FDTFluxTrackedRequest>* RequestPtr = AllRequests.Find(RequestId))
{
Request = *RequestPtr;
}
}
if (!Request.IsValid())
{
return false;
}
Request->LastErrorMessage = ErrorMessage;
ChangeRequestState(Request, EDTFluxRequestState::Failed);
TriggerCallbacks(*Request);
CleanupCallbacks(RequestId);
UE_LOG(logDTFluxNetwork, Error, TEXT("Failed request %s: %s"), *RequestId.ToString(), *ErrorMessage);
return true;
}
2025-07-11 19:04:37 +02:00
bool FDTFluxQueuedRequestManager::RetryRequest(const FGuid& RequestId)
{
2025-07-11 19:04:37 +02:00
TSharedPtr<FDTFluxTrackedRequest> Request;
{
2025-07-11 19:04:37 +02:00
FScopeLock Lock(&RequestsLock);
if (TSharedPtr<FDTFluxTrackedRequest>* RequestPtr = AllRequests.Find(RequestId))
{
2025-07-11 19:04:37 +02:00
Request = *RequestPtr;
}
}
2025-07-11 19:04:37 +02:00
if (!Request.IsValid() || !Request->CanRetry())
{
2025-07-11 19:04:37 +02:00
return false;
}
2025-07-11 19:04:37 +02:00
Request->CurrentRetries++;
Request->LastAttemptTime = FDateTime::Now();
ChangeRequestState(Request, EDTFluxRequestState::Retrying);
UE_LOG(logDTFluxNetwork, Log, TEXT("Retrying request %s (attempt %d/%d)"),
*RequestId.ToString(), Request->CurrentRetries, Request->Config.MaxRetries);
return true;
}
2025-07-11 19:04:37 +02:00
bool FDTFluxQueuedRequestManager::FindPendingRequest(
FGuid& OutRequestId,
EDTFluxApiDataType RequestType,
int32 ContestId,
int32 StageId,
int32 SplitId) const
{
2025-07-11 19:04:37 +02:00
FScopeLock Lock(&RequestsLock);
for (const auto& [RequestId, Request] : AllRequests)
{
2025-07-11 19:04:37 +02:00
if ((Request->State == EDTFluxRequestState::Pending || Request->State == EDTFluxRequestState::Sent) &&
Request->Matches(RequestType, ContestId, StageId, SplitId))
{
OutRequestId = RequestId;
return true;
}
}
return false;
}
// === ACCESSEURS ===
bool FDTFluxQueuedRequestManager::GetRequest(const FGuid& RequestId, FDTFluxTrackedRequest& OutRequest) const
{
FScopeLock Lock(&RequestsLock);
if (const TSharedPtr<FDTFluxTrackedRequest>* RequestPtr = AllRequests.Find(RequestId))
{
OutRequest = **RequestPtr;
return true;
}
return false;
}
2025-07-11 19:04:37 +02:00
const FDTFluxTrackedRequest* FDTFluxQueuedRequestManager::GetRequestPtr(const FGuid& RequestId) const
{
FScopeLock Lock(&RequestsLock);
2025-07-11 19:04:37 +02:00
if (const TSharedPtr<FDTFluxTrackedRequest>* RequestPtr = AllRequests.Find(RequestId))
{
return RequestPtr->Get();
}
return nullptr;
}
2025-07-11 19:04:37 +02:00
TArray<FDTFluxTrackedRequest> FDTFluxQueuedRequestManager::GetRequestsByState(EDTFluxRequestState State) const
{
2025-07-11 19:04:37 +02:00
FScopeLock Lock(&RequestsLock);
TArray<FDTFluxTrackedRequest> Results;
2025-07-11 19:04:37 +02:00
for (const auto& [RequestId, Request] : AllRequests)
{
2025-07-11 19:04:37 +02:00
if (Request->State == State)
{
Results.Add(*Request);
}
}
2025-07-11 19:04:37 +02:00
return Results;
}
int32 FDTFluxQueuedRequestManager::GetRequestCount(EDTFluxRequestState State) const
{
FScopeLock Lock(&RequestsLock);
int32 Count = 0;
for (const auto& [RequestId, Request] : AllRequests)
{
2025-07-11 19:04:37 +02:00
if (Request->State == State)
{
Count++;
}
}
return Count;
}
2025-07-11 19:04:37 +02:00
FDTFluxQueuedRequestManager::FRequestStatistics FDTFluxQueuedRequestManager::GetStatistics() const
{
2025-07-11 19:04:37 +02:00
FScopeLock RequestsLock_Local(&RequestsLock);
FScopeLock MetricsLock_Local(&MetricsLock);
2025-07-11 19:04:37 +02:00
FRequestStatistics Stats;
for (const auto& [RequestId, Request] : AllRequests)
{
2025-07-11 19:04:37 +02:00
switch (Request->State)
{
2025-07-11 19:04:37 +02:00
case EDTFluxRequestState::Pending:
case EDTFluxRequestState::Sent:
case EDTFluxRequestState::Retrying:
Stats.Pending++;
break;
case EDTFluxRequestState::Completed:
Stats.Completed++;
break;
case EDTFluxRequestState::Failed:
case EDTFluxRequestState::TimedOut:
Stats.Failed++;
break;
}
2025-07-11 19:04:37 +02:00
}
Stats.TotalRequests = TotalRequests;
return Stats;
}
// === NETTOYAGE ===
int32 FDTFluxQueuedRequestManager::CleanupCompletedRequests(float OlderThanSeconds)
{
2025-07-11 19:04:37 +02:00
FScopeLock Lock(&RequestsLock);
2025-07-11 19:04:37 +02:00
TArray<FGuid> OldRequests;
const FDateTime Threshold = FDateTime::Now() - FTimespan::FromSeconds(OlderThanSeconds);
2025-07-11 19:04:37 +02:00
for (const auto& [RequestId, Request] : AllRequests)
{
2025-07-11 19:04:37 +02:00
if ((Request->State == EDTFluxRequestState::Completed || Request->State == EDTFluxRequestState::Failed ||
Request->State == EDTFluxRequestState::TimedOut) && Request->CompletedAt < Threshold)
{
2025-07-11 19:04:37 +02:00
OldRequests.Add(RequestId);
}
}
2025-07-11 19:04:37 +02:00
for (const FGuid& RequestId : OldRequests)
{
AllRequests.Remove(RequestId);
}
2025-07-11 19:04:37 +02:00
return OldRequests.Num();
}
void FDTFluxQueuedRequestManager::ClearAllRequests()
{
FScopeLock RequestsLock_Local(&RequestsLock);
FScopeLock CallbacksLock_Local(&CallbacksLock);
AllRequests.Empty();
SuccessCallbacks.Empty();
ErrorCallbacks.Empty();
UE_LOG(logDTFluxNetwork, Log, TEXT("Cleared all requests"));
}
void FDTFluxQueuedRequestManager::Tick(float DeltaTime)
{
if (!bIsInitialized.load())
return;
// Mise à jour des timers
TimeSinceLastTimeoutCheck += DeltaTime;
TimeSinceLastRetryCheck += DeltaTime;
// Vérifier les timeouts
if (TimeSinceLastTimeoutCheck >= TimeoutCheckInterval)
{
ProcessTimeouts();
TimeSinceLastTimeoutCheck = 0.0f;
}
// Vérifier les retries
if (TimeSinceLastRetryCheck >= RetryCheckInterval)
{
ProcessRetries();
TimeSinceLastRetryCheck = 0.0f;
}
}
void FDTFluxQueuedRequestManager::ChangeRequestState(TSharedPtr<FDTFluxTrackedRequest> Request,
EDTFluxRequestState NewState)
{
if (!Request.IsValid())
return;
const EDTFluxRequestState OldState = Request->State;
Request->State = NewState;
// Déclencher l'événement de changement d'état
OnRequestStateChanged.Broadcast(Request->RequestId, NewState);
UE_LOG(logDTFluxNetwork, VeryVerbose, TEXT("DTFluxQueuedRequestManager: Request %s state changed from %s to %s"),
*Request->RequestId.ToString(),
*UEnum::GetValueAsString(OldState),
*UEnum::GetValueAsString(NewState));
}
void FDTFluxQueuedRequestManager::ProcessTimeouts()
{
FScopeLock Lock(&RequestsLock);
TArray<TSharedPtr<FDTFluxTrackedRequest>> TimedOutRequests;
for (const auto& Pair : AllRequests)
{
const auto& Request = Pair.Value;
if (Request->HasTimedOut())
{
TimedOutRequests.Add(Request);
}
}
for (const auto& Request : TimedOutRequests)
{
Request->LastErrorMessage = FString::Printf(
TEXT("Request timed out after %.1f seconds"), Request->Config.TimeoutSeconds);
if (Request->CanRetry())
{
Request->CurrentRetries++;
ChangeRequestState(Request, EDTFluxRequestState::Retrying);
}
else
{
2025-07-11 19:04:37 +02:00
ChangeRequestState(Request, EDTFluxRequestState::TimedOut);
TriggerCallbacks(*Request);
OnRequestFailed.Broadcast(*Request);
}
}
2025-07-11 19:04:37 +02:00
}
void FDTFluxQueuedRequestManager::ProcessRetries()
{
FScopeLock Lock(&RequestsLock);
2025-07-11 19:04:37 +02:00
const FDateTime Now = FDateTime::Now();
TArray<TSharedPtr<FDTFluxTrackedRequest>> ReadyToRetry;
for (const auto& Pair : AllRequests)
{
2025-07-11 19:04:37 +02:00
const auto& Request = Pair.Value;
if (Request->State == EDTFluxRequestState::Retrying)
{
const float ElapsedSinceLastAttempt = (Now - Request->LastAttemptTime).GetTotalSeconds();
if (ElapsedSinceLastAttempt >= Request->GetRetryDelay())
{
ReadyToRetry.Add(Request);
}
}
}
2025-07-11 19:04:37 +02:00
for (const auto& Request : ReadyToRetry)
{
2025-07-11 19:04:37 +02:00
Request->LastAttemptTime = Now;
ChangeRequestState(Request, EDTFluxRequestState::Pending);
}
2025-07-11 19:04:37 +02:00
}
2025-07-11 19:04:37 +02:00
void FDTFluxQueuedRequestManager::TriggerCallbacks(const FDTFluxTrackedRequest& Request)
{
2025-07-11 19:04:37 +02:00
FScopeLock Lock(&CallbacksLock);
if (Request.State == EDTFluxRequestState::Completed)
{
2025-07-11 19:04:37 +02:00
// Success Cb
const FOnDTFluxRequestSuccess* SuccessCallback = SuccessCallbacks.Find(Request.RequestId);
if (SuccessCallback && SuccessCallback->IsBound())
{
SuccessCallback->Execute(Request);
}
}
2025-07-11 19:04:37 +02:00
else if (Request.State == EDTFluxRequestState::Failed || Request.State == EDTFluxRequestState::TimedOut)
{
2025-07-11 19:04:37 +02:00
// Error Cb
const FOnDTFluxRequestError* ErrorCallback = ErrorCallbacks.Find(Request.RequestId);
if (ErrorCallback && ErrorCallback->IsBound())
{
ErrorCallback->Execute(Request, Request.LastErrorMessage);
}
}
2025-07-11 19:04:37 +02:00
}
2025-07-11 19:04:37 +02:00
void FDTFluxQueuedRequestManager::CleanupCallbacks(const FGuid& RequestId)
{
FScopeLock Lock(&CallbacksLock);
SuccessCallbacks.Remove(RequestId);
ErrorCallbacks.Remove(RequestId);
}
2025-07-11 19:04:37 +02:00
void FDTFluxQueuedRequestManager::OnParsingCompleted(const FGuid& RequestId,
TSharedPtr<FDTFluxServerResponse> ParsedResponse, bool bSuccess)
{
UE_LOG(logDTFluxNetwork, Log, TEXT("FDTFluxQueuedRequestManager::OnParsingCompleted() request %s"),
*RequestId.ToString())
TSharedPtr<FDTFluxTrackedRequest> Request;
{
FScopeLock Lock(&RequestsLock);
2025-07-11 19:04:37 +02:00
auto* RequestPtr = AllRequests.Find(RequestId);
if (!RequestPtr || !RequestPtr->IsValid())
{
UE_LOG(logDTFluxNetwork, Error,
TEXT(
"DTFluxQueuedRequestManager::OnParsingCompleted() RequestId%s [InvalidRequestId=%s], [RequestPtrValid=%s]"
),
*RequestId.ToString(), RequestPtr ? TEXT("true") : TEXT("false"),
RequestPtr->IsValid() ? TEXT("true") : TEXT("false"));
return;
}
Request = *RequestPtr;
}
2025-07-11 19:04:37 +02:00
if (bSuccess && ParsedResponse.IsValid())
{
2025-07-11 19:04:37 +02:00
Request->ParsedResponse = ParsedResponse;
Request->bIsResponseParsed = true;
EDTFluxRequestState NewState = EDTFluxRequestState::Completed;
ChangeRequestState(Request, NewState);
UE_LOG(logDTFluxNetwork, Log,
2025-07-11 19:04:37 +02:00
TEXT("DTFluxQueuedRequestManager: Async parsing completed for request %s"),
*RequestId.ToString());
}
else
{
Request->LastErrorMessage = TEXT("Async parsing failed");
ChangeRequestState(Request, EDTFluxRequestState::Failed);
UE_LOG(logDTFluxNetwork, Error, TEXT("Async parsing failed for request %s"), *RequestId.ToString());
}
TriggerCallbacks(*Request);
CleanupCallbacks(RequestId);
}
2025-07-11 19:04:37 +02:00
void FDTFluxQueuedRequestManager::OnParsingFailed(const FGuid& RequestId, const FString& ErrorMessage)
{
2025-07-11 19:04:37 +02:00
UE_LOG(logDTFluxNetwork, Error, TEXT("DTFluxQueuedRequestManager: Async parsing failed for request %s: %s"),
*RequestId.ToString(),
*ErrorMessage);
FailRequest(RequestId, FString::Printf(TEXT("Parsing failed: %s"), *ErrorMessage));
}