// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
namespace EpicGames.Horde.Storage
{
///
/// Reference to another node in storage. This type is similar to , but without a hash.
///
public interface IBlobRef
{
///
/// Accessor for the innermost import
///
IBlobRef Innermost { get; }
///
/// Flush the referenced data to underlying storage
///
ValueTask FlushAsync(CancellationToken cancellationToken = default);
///
/// Reads the blob's data
///
/// Cancellation token for the operation
ValueTask ReadBlobDataAsync(CancellationToken cancellationToken = default);
///
/// Attempt to get a path for this blob.
///
/// Receives the blob path on success.
/// True if a path was available, false if the blob has not yet been flushed to storage.
bool TryGetLocator([NotNullWhen(true)] out BlobLocator locator);
}
///
/// Typed interface to a particular blob handle
///
/// Type of the deserialized blob
public interface IBlobRef : IBlobRef
{
///
/// Options for deserializing the blob
///
BlobSerializerOptions? SerializerOptions { get; }
}
///
/// Extension methods for
///
public static class BlobRefExtensions
{
class TypedBlobRef : IBlobRef
{
readonly IBlobRef _inner;
///
public BlobSerializerOptions? SerializerOptions { get; }
public IBlobRef Innermost => throw new NotImplementedException();
public TypedBlobRef(IBlobRef inner, BlobSerializerOptions? serializerOptions)
{
_inner = inner;
SerializerOptions = serializerOptions;
}
public ValueTask FlushAsync(CancellationToken cancellationToken = default)
=> _inner.FlushAsync(cancellationToken);
public ValueTask ReadBlobDataAsync(CancellationToken cancellationToken = default)
=> _inner.ReadBlobDataAsync(cancellationToken);
public bool TryGetLocator([NotNullWhen(true)] out BlobLocator locator)
=> _inner.TryGetLocator(out locator);
}
///
/// Create a typed blob reference
///
/// Target type
/// Blob referfence to wrap
/// Options for deserializing the blob
public static IBlobRef ForType(this IBlobRef blobRef, BlobSerializerOptions? serializerOptions = null)
=> new TypedBlobRef(blobRef, serializerOptions);
///
/// Gets a path to this blob that can be used to describe blob references over the wire.
///
/// Handle to query
public static BlobLocator GetLocator(this IBlobRef import)
{
BlobLocator locator;
if (!import.TryGetLocator(out locator))
{
throw new InvalidOperationException("Blob has not yet been written to storage");
}
return locator;
}
}
}