Skip to content

Handle kDrive rate-limit responses with bounded backoff #9

Description

@OpenCow42

Summary

potassiumProvider should recognize remote API responses that mean the client has reached a server-side limitation, especially HTTP 429 Too Many Requests and any confirmed Infomaniak/kDrive throttle response, then delay further work using bounded backoff rather than immediately failing or causing File Provider to retry in a tight loop.

Why this matters

The provider already maps remote HTTP failures into File Provider errors, and recent work fixed one retry-storm path around virtual working-set metadata. Rate-limit responses are a broader version of the same risk: if kDrive says “slow down”, the provider should preserve system responsiveness, avoid extra API pressure, and surface a recoverable temporary state.

Current evidence

  • PotassiumProviderCore/KDriveRemoteService.swift wraps remote calls in performNetworkOperation, logs HTTP status, and classifies APIClientError.unacceptableStatusCode through KDriveRemoteErrorClassifier.
  • potassiumProviderFileProvider/FileProviderRuntime.swift maps API rejections to NSFileProviderError recovery classes.
  • potassiumChannel currently exposes APIClientError.unacceptableStatusCode(Int, body:), but not response headers, so Retry-After cannot currently be honored by the provider.

Proposed implementation

  • Extend potassiumChannel’s HTTP error surface to preserve safe response metadata needed for retry policy, at minimum HTTP status and Retry-After, without logging sensitive bodies or headers.
  • Add a typed throttling classification in KDriveRemoteErrorClassifier, covering 429 and any confirmed Infomaniak limitation status/body pattern.
  • Add a provider-side retry/backoff policy with jitter, a max delay, and a max retry budget. Prefer Retry-After when present; otherwise use exponential backoff.
  • Apply the policy only to idempotent/read-style operations first: metadata fetches, listings, thumbnails, and downloads. Mutating operations should either avoid automatic retry or retry only when the request semantics are proven safe.
  • When the retry budget is exhausted, map the failure to a recoverable File Provider error such as server unreachable / cannot synchronize, and record a concise diagnostic that does not include private response data.
  • Keep cancellation responsive during sleeps and transfers.

Acceptance criteria

  • A mocked 429 with Retry-After causes the provider to wait approximately that duration before retrying, then succeeds without surfacing an activity failure.
  • A mocked 429 without Retry-After uses bounded exponential backoff with jitter and stops after the configured retry budget.
  • A cancelled File Provider operation exits promptly during a backoff sleep.
  • Non-throttling errors keep their current mapping behavior: 401 remains not authenticated, 507 remains insufficient quota, 5xx remains server unreachable.
  • Tests cover the classifier, retry policy, and provider behavior with an injectable clock/sleeper so the suite stays fast.

Suggested validation

xcodebuild test -project potassiumProvider.xcodeproj -scheme potassiumProvider -destination 'platform=macOS' -only-testing:potassiumProviderTests

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions