Providers and adapters

Writing an ICloudTransport properly — honest capabilities, preconditions, retry hints and never throwing for an expected failure.

Cloud NexusForge Persistence 0.2.0 Updated

The seam is four methods#

csharp
public interface ICloudTransport
{
    CloudProviderCapabilities Capabilities { get; }
    bool LooksOnline { get; }
    Task<PersistenceResult<CloudObjectMetadata>> PutAsync(
        string key, ReadOnlyMemory<byte> content, CloudWriteCondition condition, CancellationToken cancellationToken);
    Task<PersistenceResult<CloudDownload>> GetAsync(string key, CancellationToken cancellationToken);
    Task<PersistenceResult<IReadOnlyList<CloudObjectMetadata>>> ListAsync(string prefix, CancellationToken cancellationToken);
    Task<PersistenceResult<bool>> DeleteAsync(string key, CloudWriteCondition condition, CancellationToken cancellationToken);
}

Nothing about saves appears in it: bytes in, bytes out, with a condition attached. That is what keeps the package vendor-neutral.

Four rules that make a transport a good citizen#

  1. Never throw for an expected failure. Return a PersistenceResult with a code from CloudErrors. A thrown exception inside a transport is treated as a framework defect, not as a service condition.
  2. Declare your capabilities honestly. CloudProviderCapabilities drives the framework's decisions; claiming conditional-write support you do not have is how one device silently overwrites another's save.
  3. Report LooksOnline. It is a hint, not an oracle — a transport that reports offline makes the framework queue instead of hammering a dead connection.
  4. Pass on the retry hint. When your service returns Retry-After, put it in the error so CloudRetrier honours it without exceeding the configured ceiling.
csharp
public CloudProviderCapabilities Capabilities => CloudProviderCapabilities.ForTransport(
    supportsConditionalWrites: true,
    supportsList: true,
    supportsDelete: true,
    maximumObjectBytes: 8L * 1024 * 1024);

Preconditions are where correctness lives#

text
Send your service's own precondition - an ETag, a revision, a version header.
If it refuses, return CloudErrors.PreconditionRefused(...).
The framework will NOT retry over the top of it, because retrying a lost race
is how you overwrite the winner.

Testing a transport with no network#

FakeCloudTransport is an in-memory transport with failure injection (offline, refused preconditions, 5xx, throttling, timeouts, corrupt payloads). It is what the framework's own cloud behaviour is verified against — and it tests the framework, not your provider's semantics. You still need to test against the real service.

Next#

Something wrong on this page? Every page here describes behaviour that is checked in the repository. If a page and the package disagree, the package wins.

Report a documentation problem · Frequently asked questions · Troubleshooting