Files
UnrealEngineUWP/Engine/Source/Developer/IoStoreUtilities/Internal/ZenStoreHttpClient.h
zousar shaker 082e9969db [Backout] - CL34481610
[FYI] Zousar.Shaker
Original CL Desc
-----------------------------------------------------------------
Incremental step towards being able to stage to both a pak build as well as a nopak (streamng) build from a snapshot entirely stored in zenserver (no loose files on the filesystem except a ue.projectstore file).
Key changes:
- Removed the use of cookedfiles.manifest
- Changed IoStore mode of UnrealPak to  be capable of getting zenserver launch data from either a package store manifest (cbobject, metadata) OR a project store marker file (json)
- Ensured that the UAT and IoStore mode of UnrealPak can launch zenserver reliably by passing along the SponsorProcessId when launching zenserver
- Ensured that shader archives (and their accompanying json metadata files) can be read either as loose files on disk or directly from zenserver if it the data for them is internal to zenserver (ie: they have a valid  chunk id)
Remaining work:
- Pak mode of UnrealPak must be able to launch zenserver and pull data from it.

#rb PJ.Kack

[CL 34498668 by zousar shaker in ue5-main branch]
2024-06-19 10:15:01 -04:00

108 lines
3.5 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Async/Future.h"
#include "Containers/Array.h"
#include "Containers/StringView.h"
#include "Experimental/ZenServerInterface.h"
#include "HAL/CriticalSection.h"
#include "HAL/Platform.h"
#include "IO/IoDispatcher.h"
#include "Misc/StringBuilder.h"
#include "Serialization/CompactBinaryPackage.h"
#include "Templates/UniquePtr.h"
class FCbPackage;
class FCbObject;
namespace UE {
namespace Zen {
struct FZenHttpRequestPool;
class FZenHttpRequest;
enum class EContentType;
}
/**
* HTTP protocol implementation of Zen Store client interface
*/
class IOSTOREUTILITIES_API FZenStoreHttpClient
{
public:
FZenStoreHttpClient();
FZenStoreHttpClient(FStringView HostName, uint16 Port);
FZenStoreHttpClient(UE::Zen::FServiceSettings&& InSettings);
~FZenStoreHttpClient();
bool TryCreateProject(FStringView InProjectId, FStringView InOplogId, FStringView ServerRoot,
FStringView EngineRoot, FStringView ProjectRoot,
FStringView ProjectFilePath);
bool TryCreateOplog(FStringView InProjectId, FStringView InOplogId, FStringView InOplogLifetimeMarkerPath, bool bFullBuild);
void InitializeReadOnly(FStringView InProjectId, FStringView InOplogId);
bool IsConnected() const;
void StartBuildPass();
TIoStatusOr<uint64> EndBuildPass(FCbPackage OpEntry);
TIoStatusOr<uint64> AppendOp(FCbPackage OpEntry);
TIoStatusOr<uint64> GetChunkSize(const FIoChunkId& Id);
TIoStatusOr<FIoBuffer> ReadChunk(const FIoChunkId& Id, uint64 Offset = 0, uint64 Size = ~0ull);
TIoStatusOr<FIoBuffer> ReadOpLogAttachment(FStringView Id);
#if UE_WITH_ZEN
const TCHAR* GetHostName() const { return ZenService.GetInstance().GetHostName(); }
uint16 GetPort() const { return ZenService.GetInstance().GetPort(); }
const UE::Zen::FZenServiceInstance& GetZenServiceInstance() const { return ZenService.GetInstance(); }
#else // Default to localhost:8558 for platforms where Zen wouldn't be supported yet
const TCHAR* GetHostName() const { return TEXT("localhost"); }
uint16 GetPort() const { return 8558; }
#endif
TFuture<TIoStatusOr<FCbObject>> GetOplog();
TFuture<TIoStatusOr<FCbObject>> GetFiles();
TFuture<TIoStatusOr<FCbObject>> GetChunkInfos();
static const UTF8CHAR* FindOrAddAttachmentId(FUtf8StringView AttachmentText);
static const UTF8CHAR* FindAttachmentId(FUtf8StringView AttachmentText);
private:
TIoStatusOr<FIoBuffer> ReadOpLogUri(FStringBuilderBase& ChunkUri, uint64 Offset = 0, uint64 Size = ~0ull);
bool Download(Zen::FZenHttpRequest& Request, FStringView Uri, TArray64<uint8>* Buffer, Zen::EContentType AcceptType);
bool Post(Zen::FZenHttpRequest& Request, FStringView Uri, FCbObjectView Obj);
bool Post(Zen::FZenHttpRequest& Request, FStringView Uri, FMemoryView Payload);
bool Delete(Zen::FZenHttpRequest& Request, FStringView Uri);
bool ShouldRecoverAndRetry(Zen::FZenHttpRequest& Request);
static const uint32 PoolEntryCount;
struct SaltGenerator
{
SaltGenerator();
inline int32_t Next()
{
const uint32_t A = ++GOpCounter;
return static_cast<int32_t>((A ^ (SaltBase + (A << 6) + (A >> 2))) & 0x7fffffffu);
}
private:
static std::atomic<uint32> GOpCounter;
const uint32_t SaltBase;
};
#if UE_WITH_ZEN
UE::Zen::FScopeZenService ZenService;
#endif
TUniquePtr<Zen::FZenHttpRequestPool> RequestPool;
SaltGenerator SaltGen;
FString OplogPath;
FString OplogNewEntryPath;
FString OplogPrepNewEntryPath;
FString TempDirPath;
const uint64 StandaloneThresholdBytes = 1 * 1024 * 1024;
bool bAllowRead = false;
bool bAllowEdit = false;
bool bConnectionSucceeded = false;
};
}