HTTPRequest Inconsistently firesOnProcessRequestComplete

Hello,

My game is on the edge to be finished but I’m having some trouble with the reliability of the HTTP library. Sometimes my request simply doesn’t get a response! The server handles it just fine as shown in the server logs but the game doesn’t get a response

This is my class.

#pragma once

#include "CoreMinimal.h"
#include "Runtime/Online/HTTP/Public/Http.h"
#include "Json.h"
#include "PlayerCharacter.h"
#include "Inventory.h"
#include "MasterServer.generated.h"

#define LOCAL_ENVIRONMENT false
#define MASTER_SERVER_IP "XXXXXXX"
#define LOCAL_MASTER_SERVER_IP "127.0.0.1:5000"

UCLASS()
class DAYDSERVER_API UMasterServer : public UObject
{
	GENERATED_BODY()

public:
	// Sets default values for this actor's properties
	UMasterServer(const class FObjectInitializer& ObjectInitializer);

	FHttpModule* Http;

	void RequestCharacterData(uint64 steam_id, TFunction<void(uint64 steam_id, FVector position, FRotator rotation, TArray<FItemInformation> gear, TArray<FItemInformation> pockets)> Callback);
	void ReceivedCharacterData(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful, TFunction<void(uint64 steam_id, FVector position, FRotator rotation, TArray<FItemInformation> gear, TArray<FItemInformation> pockets)> Callback);

	void CommitCharacterData(uint64 steam_id, float position[3], float yaw, APlayerCharacter* player_character);
};

And my class body is as follows:

#include "MasterServer.h"

UMasterServer::UMasterServer(const class FObjectInitializer& ObjectInitializer): Super(ObjectInitializer)
{
	Http = &FHttpModule::Get();
}

void UMasterServer::RequestCharacterData(uint64 steam_id, TFunction<void(uint64 steam_id, FVector position, FRotator rotation, TArray<FItemInformation> gear, TArray<FItemInformation> pockets)> Callback)
{
	TSharedRef<IHttpRequest> Request = Http->CreateRequest();
	Request->OnProcessRequestComplete().BindUObject(this, &UMasterServer::ReceivedCharacterData, Callback);

	FString url = FString::Printf(TEXT("http://%s/user/%llu"), *FString(LOCAL_ENVIRONMENT ? LOCAL_MASTER_SERVER_IP : MASTER_SERVER_IP), steam_id);

	Request->SetURL(url);
	Request->SetVerb("GET");
	Request->SetHeader(TEXT("User-Agent"), "X-UnrealEngine-Agent");
	Request->SetHeader("Content-Type", TEXT("application/json"));

	Request->ProcessRequest();

	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, TEXT("Requested player data"), false);
}

void UMasterServer::ReceivedCharacterData(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful, TFunction<void(uint64 steam_id, FVector position, FRotator rotation, TArray<FItemInformation> gear, TArray<FItemInformation> pockets)> Callback)
{
	if (bWasSuccessful && Request->GetResponse()->GetResponseCode() == 200)
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, TEXT("Player data arrived"), false);
		TSharedPtr<FJsonObject> JsonObject;
		TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(Response->GetContentAsString());

		if (FJsonSerializer::Deserialize(Reader, JsonObject))
		{
			FString steam_id_string = JsonObject->GetStringField("steam_id");
			FVector position = FVector((float)JsonObject->GetNumberField("pos_x"), (float)JsonObject->GetNumberField("pos_y"), (float)JsonObject->GetNumberField("pos_z"));
			FRotator rotation = FRotator(0.0f, (float)JsonObject->GetNumberField("yaw"), 0.0f);

			uint64 steam_id = FCString::Strtoui64(*steam_id_string, NULL, 10);

			TArray<FItemInformation> gear;
			TArray<FItemInformation> pockets;

			TArray<TSharedPtr<FJsonValue>> inventories = JsonObject->GetArrayField("inventories");

			for (int i = 0; i < inventories.Num(); i++) {
				TSharedPtr<FJsonObject> inventory = inventories[i]->AsObject();

				int item_id = inventory->GetIntegerField("item_id");
				int inventory_id = inventory->GetIntegerField("inventory_id");
				int position_x = inventory->GetIntegerField("position_x");
				int position_y = inventory->GetIntegerField("position_y");
				int amount = inventory->GetIntegerField("amount");

				FItemInformation item;
				item.id = item_id;
				item.inventory_position_x = position_x;
				item.inventory_position_y = position_y;
				item.amount = amount;

				switch (inventory_id)
				{
				case (uint8)InventoryTypes::Gear:
					gear.Add(item);
					break;
				case (uint8)InventoryTypes::Pockets:
					pockets.Add(item);
					break;
				}
			}

			GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("Data parsed"), false);

			Callback(steam_id, position, rotation, gear, pockets);
		}
	}
	else
	{
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Green, TEXT("Character data request failed"), false);
	}
}

void UMasterServer::CommitCharacterData(uint64 steam_id, float position[3], float yaw, APlayerCharacter* player_character)
{
	FHttpModule* Http = &FHttpModule::Get();
	TSharedRef<IHttpRequest> Request = Http->CreateRequest();

	FString url = FString::Printf(TEXT("http://%s/user/%llu"), *FString(LOCAL_ENVIRONMENT ? LOCAL_MASTER_SERVER_IP : MASTER_SERVER_IP), steam_id);

	Request->SetURL(url);
	Request->SetVerb("POST");
	Request->SetHeader("Content-Type", TEXT("application/json"));

	FString payload = FString::Printf(TEXT("{\"pos_x\":%f, \"pos_y\":%f, \"pos_z\":%f, \"yaw\":%f, \"inventory\": ["), position[0], position[1], position[2], yaw);

	bool first = true;
	for (FItemInformation item_information : player_character->gear->items)
	{
		if (!first)
			payload.Append(",");

		payload.Append(FString::Printf(TEXT("{ \"item_id\":%d, \"inventory_id\":%d, \"position_x\":%d, \"position_y\":%d, \"amount\":%d }"),
			item_information.id,
			(uint8)InventoryTypes::Gear,
			item_information.inventory_position_x,
			item_information.inventory_position_y,
			item_information.amount));

		first = false;
	}

	for (FItemInformation item_information : player_character->pockets->items)
	{
		if (!first)
			payload.Append(",");

		payload.Append(FString::Printf(TEXT("{ \"item_id\":%d, \"inventory_id\":%d, \"position_x\":%d, \"position_y\":%d, \"amount\":%d }"),
			item_information.id,
			(uint8)InventoryTypes::Pockets,
			item_information.inventory_position_x,
			item_information.inventory_position_y,
			item_information.amount));

		first = false;
	}

	payload.Append("]}");

	Request->SetContentAsString(payload);

	Request->ProcessRequest();

	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("Player data commited"), false);
}

Anyone has any clues why ReceivedCharacterData is more often than not, not called?? The server is a Python API running on GUnicorn and NGINX handling requests. I also run this same script with a simple Python server and the behavior persists.