Skip to content

Solution to https://community.cesium.com/t/it-took-more-than-ten-seconds-to-exit/23354 problem #1664

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions Source/CesiumRuntime/Private/Cesium3DTileset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include "StereoRendering.h"
#include "UnrealPrepareRendererResources.h"
#include "VecMath.h"
#include "UnrealAssetAccessor.h"
#include <glm/gtc/matrix_inverse.hpp>
#include <memory>
#include <spdlog/spdlog.h>
Expand Down Expand Up @@ -2293,6 +2294,27 @@ void ACesium3DTileset::BeginDestroy() {

bool ACesium3DTileset::IsReadyForFinishDestroy() {
bool ready = AActor::IsReadyForFinishDestroy();

//If the request has not ended yet, actively cancel the request
{
FScopeLock lock(&UnrealAssetAccessor::_pendingRequestsLock);
for (const TSharedRef<IHttpRequest, ESPMode::ThreadSafe>& pRequest : UnrealAssetAccessor::_pendingRequests) {
EHttpRequestStatus::Type status = pRequest->GetStatus();
if (status == EHttpRequestStatus::NotStarted || status == EHttpRequestStatus::Processing) {
const FString& requestUrl = pRequest->GetURL();
UE_LOG(LogTemp, Log, TEXT("3DTiles URL = %s, Request URL = %s"), *this->Url, *requestUrl);
if (this->TilesetSource == ETilesetSource::FromCesiumIon && requestUrl.Contains("CesiumWorldTerrain"))
pRequest->CancelRequest();
else if (this->TilesetSource == ETilesetSource::FromUrl) {
FString originUrl = this->Url;
originUrl.RemoveFromEnd(TEXT("tileset.json"));
if (requestUrl.Contains(UCesiumRasterOverlay::ExtractCleanBaseUrl(originUrl)))
pRequest->CancelRequest();
}
}
}
}

ready &= this->_tilesetsBeingDestroyed == 0;

if (!ready) {
Expand Down
5 changes: 5 additions & 0 deletions Source/CesiumRuntime/Private/CesiumBingMapsRasterOverlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,8 @@ UCesiumBingMapsRasterOverlay::CreateOverlay(
"",
options);
}

bool UCesiumBingMapsRasterOverlay::IsReadyForFinishDestroy() {
this->SetUrl(TEXT("https://dev.virtualearth.net"));
return Super::IsReadyForFinishDestroy();
}
5 changes: 5 additions & 0 deletions Source/CesiumRuntime/Private/CesiumIonServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,8 @@ CesiumAsync::Future<void> UCesiumIonServer::ResolveApiUrl() {
});
}
#endif

bool UCesiumIonRasterOverlay::IsReadyForFinishDestroy() {
this->SetUrl(this->CesiumIonServer->ApiUrl);
return Super::IsReadyForFinishDestroy();
}
40 changes: 38 additions & 2 deletions Source/CesiumRuntime/Private/CesiumRasterOverlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "CesiumAsync/IAssetResponse.h"
#include "CesiumRasterOverlays/RasterOverlayLoadFailureDetails.h"
#include "CesiumRuntime.h"
#include "UnrealAssetAccessor.h"

FCesiumRasterOverlayLoadFailure OnCesiumRasterOverlayLoadFailure{};

Expand Down Expand Up @@ -56,8 +57,9 @@ void UCesiumRasterOverlay::AddToTileset() {
options.showCreditsOnScreen = this->ShowCreditsOnScreen;
options.rendererOptions = &this->rendererOptions;
options.loadErrorCallback =
[this](const CesiumRasterOverlays::RasterOverlayLoadFailureDetails&
details) {
[this](
const CesiumRasterOverlays::RasterOverlayLoadFailureDetails&
details) {
static_assert(
uint8_t(ECesiumRasterOverlayLoadType::CesiumIon) ==
uint8_t(CesiumRasterOverlays::RasterOverlayLoadType::CesiumIon));
Expand Down Expand Up @@ -195,6 +197,40 @@ void UCesiumRasterOverlay::OnComponentDestroyed(bool bDestroyingHierarchy) {

bool UCesiumRasterOverlay::IsReadyForFinishDestroy() {
bool ready = Super::IsReadyForFinishDestroy();

// If the request has not ended yet, actively cancel the request
{
FScopeLock lock(&UnrealAssetAccessor::_pendingRequestsLock);
const FString originBaseUrl = ExtractCleanBaseUrl(_url);
for (const TSharedRef<IHttpRequest, ESPMode::ThreadSafe>& pRequest :
UnrealAssetAccessor::_pendingRequests) {
EHttpRequestStatus::Type status = pRequest->GetStatus();
if (status == EHttpRequestStatus::NotStarted ||
status == EHttpRequestStatus::Processing) {
const FString& requestUrl = pRequest->GetURL();
const FString requestBaseUrl = ExtractCleanBaseUrl(requestUrl);

UE_LOG(
LogTemp,
Log,
TEXT("WMTS URL = %s, Request URL = %s"),
*_url,
*requestUrl);
if (_url == TEXT("https://dev.virtualearth.net") ||
_url == TEXT("https://api.cesium.com")) {
// bing map
if (requestUrl.Contains(TEXT("tiles.virtualearth.net/tiles"))) {
pRequest->CancelRequest();
}
} else if (originBaseUrl == requestBaseUrl) {
// other map(china Tianditu map\mapbox sate1lite map\arcgis online
// world map\and other map(with kvp or restful))
pRequest->CancelRequest();
}
}
}
}

ready &= this->_overlaysBeingDestroyed == 0;

if (!ready) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,8 @@ UCesiumTileMapServiceRasterOverlay::CreateOverlay(
tmsOptions,
options);
}

bool UCesiumTileMapServiceRasterOverlay::IsReadyForFinishDestroy() {
this->SetUrl(this->Url);
return Super::IsReadyForFinishDestroy();
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,8 @@ UCesiumUrlTemplateRasterOverlay::CreateOverlay(
urlTemplateOptions,
options);
}

bool UCesiumUrlTemplateRasterOverlay::IsReadyForFinishDestroy() {
this->SetUrl(this->TemplateUrl);
return Super::IsReadyForFinishDestroy();
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,8 @@ UCesiumWebMapServiceRasterOverlay::CreateOverlay(
wmsOptions,
options);
}

bool UCesiumWebMapServiceRasterOverlay::IsReadyForFinishDestroy() {
this->SetUrl(this->BaseUrl);
return Super::IsReadyForFinishDestroy();
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,8 @@ UCesiumWebMapTileServiceRasterOverlay::CreateOverlay(
wmtsOptions,
options);
}

bool UCesiumWebMapTileServiceRasterOverlay::IsReadyForFinishDestroy() {
this->SetUrl(this->BaseUrl);
return Super::IsReadyForFinishDestroy();
}
38 changes: 38 additions & 0 deletions Source/CesiumRuntime/Private/UnrealAssetAccessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ void rejectPromiseOnUnsuccessfulConnection(

} // namespace

TSet<TSharedRef<IHttpRequest, ESPMode::ThreadSafe>> UnrealAssetAccessor::_pendingRequests;
FCriticalSection UnrealAssetAccessor::_pendingRequestsLock;

CesiumAsync::Future<std::shared_ptr<CesiumAsync::IAssetRequest>>
UnrealAssetAccessor::get(
const CesiumAsync::AsyncSystem& asyncSystem,
Expand Down Expand Up @@ -211,6 +214,12 @@ UnrealAssetAccessor::get(

pRequest->AppendToHeader(TEXT("User-Agent"), userAgent);

// Add to the pending list when initiating a request
{
FScopeLock lock(&UnrealAssetAccessor::_pendingRequestsLock);
UnrealAssetAccessor::_pendingRequests.Add(pRequest);
}

pRequest->OnProcessRequestComplete().BindLambda(
[promise, CESIUM_TRACE_LAMBDA_CAPTURE_TRACK()](
FHttpRequestPtr pRequest,
Expand All @@ -219,6 +228,17 @@ UnrealAssetAccessor::get(
CESIUM_TRACE_USE_CAPTURED_TRACK();
CESIUM_TRACE_END_IN_TRACK("requestAsset");

// Request to end removal
{
FScopeLock lock(&UnrealAssetAccessor::_pendingRequestsLock);
for (auto It = UnrealAssetAccessor::_pendingRequests.CreateIterator(); It; ++It) {
if (&(It->Get()) == pRequest.Get()) {
It.RemoveCurrent();
break;
}
}
}

if (connectedSuccessfully) {
promise.resolve(
std::make_unique<UnrealAssetRequest>(pRequest, pResponse));
Expand Down Expand Up @@ -268,6 +288,12 @@ UnrealAssetAccessor::request(

pRequest->AppendToHeader(TEXT("User-Agent"), userAgent);

// Add to the pending list when initiating a request
{
FScopeLock lock(&UnrealAssetAccessor::_pendingRequestsLock);
UnrealAssetAccessor::_pendingRequests.Add(pRequest);
}

pRequest->SetContent(TArray<uint8>(
reinterpret_cast<const uint8*>(contentPayload.data()),
contentPayload.size()));
Expand All @@ -277,6 +303,18 @@ UnrealAssetAccessor::request(
FHttpRequestPtr pRequest,
FHttpResponsePtr pResponse,
bool connectedSuccessfully) {

// Request to end removal
{
FScopeLock lock(&UnrealAssetAccessor::_pendingRequestsLock);
for (auto It = UnrealAssetAccessor::_pendingRequests.CreateIterator(); It; ++It) {
if (&(It->Get()) == pRequest.Get()) {
It.RemoveCurrent();
break;
}
}
}

if (connectedSuccessfully) {
promise.resolve(
std::make_unique<UnrealAssetRequest>(pRequest, pResponse));
Expand Down
1 change: 1 addition & 0 deletions Source/CesiumRuntime/Public/CesiumBingMapsRasterOverlay.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class CESIUMRUNTIME_API UCesiumBingMapsRasterOverlay
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
EBingMapsStyle MapStyle = EBingMapsStyle::Aerial;

virtual bool IsReadyForFinishDestroy() override;
protected:
virtual std::unique_ptr<CesiumRasterOverlays::RasterOverlay> CreateOverlay(
const CesiumRasterOverlays::RasterOverlayOptions& options = {}) override;
Expand Down
1 change: 1 addition & 0 deletions Source/CesiumRuntime/Public/CesiumIonRasterOverlay.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class CESIUMRUNTIME_API UCesiumIonRasterOverlay : public UCesiumRasterOverlay {
// UActorComponent overrides
virtual void PostLoad() override;

virtual bool IsReadyForFinishDestroy() override;
protected:
virtual std::unique_ptr<CesiumRasterOverlays::RasterOverlay> CreateOverlay(
const CesiumRasterOverlays::RasterOverlayOptions& options = {}) override;
Expand Down
2 changes: 2 additions & 0 deletions Source/CesiumRuntime/Public/CesiumRasterOverlay.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ class CESIUMRUNTIME_API UCesiumRasterOverlay : public UActorComponent {
virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override;
virtual bool IsReadyForFinishDestroy() override;

static FString ExtractCleanBaseUrl(const FString& InUrl);
protected:
/**
* The maximum number of pixels of error when rendering this overlay.
Expand Down Expand Up @@ -257,4 +258,5 @@ class CESIUMRUNTIME_API UCesiumRasterOverlay : public UActorComponent {
private:
CesiumRasterOverlays::RasterOverlay* _pOverlay;
int32 _overlaysBeingDestroyed;
FString _url;
};
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class CESIUMRUNTIME_API UCesiumTileMapServiceRasterOverlay
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
TMap<FString, FString> RequestHeaders;

virtual bool IsReadyForFinishDestroy() override;
protected:
virtual std::unique_ptr<CesiumRasterOverlays::RasterOverlay> CreateOverlay(
const CesiumRasterOverlays::RasterOverlayOptions& options = {}) override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ class CESIUMRUNTIME_API UCesiumUrlTemplateRasterOverlay
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
TMap<FString, FString> RequestHeaders;

virtual bool IsReadyForFinishDestroy() override;
protected:
virtual std::unique_ptr<CesiumRasterOverlays::RasterOverlay> CreateOverlay(
const CesiumRasterOverlays::RasterOverlayOptions& options = {}) override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class CESIUMRUNTIME_API UCesiumWebMapServiceRasterOverlay
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
TMap<FString, FString> RequestHeaders;

virtual bool IsReadyForFinishDestroy() override;
protected:
virtual std::unique_ptr<CesiumRasterOverlays::RasterOverlay> CreateOverlay(
const CesiumRasterOverlays::RasterOverlayOptions& options = {}) override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ class CESIUMRUNTIME_API UCesiumWebMapTileServiceRasterOverlay

virtual void Serialize(FArchive& Ar) override;

virtual bool IsReadyForFinishDestroy() override;
protected:
virtual std::unique_ptr<CesiumRasterOverlays::RasterOverlay> CreateOverlay(
const CesiumRasterOverlays::RasterOverlayOptions& options = {}) override;
Expand Down
3 changes: 3 additions & 0 deletions Source/CesiumRuntime/Public/UnrealAssetAccessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "HAL/Platform.h"
#include <cstddef>

class IHttpRequest;
class CESIUMRUNTIME_API UnrealAssetAccessor
: public CesiumAsync::IAssetAccessor {
public:
Expand All @@ -30,6 +31,8 @@ class CESIUMRUNTIME_API UnrealAssetAccessor

virtual void tick() noexcept override;

static TSet<TSharedRef<IHttpRequest, ESPMode::ThreadSafe>> _pendingRequests;
static FCriticalSection _pendingRequestsLock;
private:
CesiumAsync::Future<std::shared_ptr<CesiumAsync::IAssetRequest>> getFromFile(
const CesiumAsync::AsyncSystem& asyncSystem,
Expand Down