Skip to content

Add storage-pressure admission before backing storage is exhausted #131

Description

@rmcdaniel

Problem

A runtime can reach its backing filesystem or native writer quota while logical namespace quotas still permit operations. In a native MySQL reproduction, committed data remained recoverable, but a full quota caused Table is full failures in maintenance and command writes; a worker task completion returned HTTP 500. Logical object/row limits are not a physical storage reserve.

Implementation scope

Add an opt-in, deployment-neutral storage-pressure input to Server. An operator-owned local health snapshot reports the resource identity, observation time and whether the resource is normal, draining or fenced. Server must fail closed on missing, stale or malformed configured observations, without needing writes to the already constrained database.

  • Normal: preserve current behavior.
  • Draining: reject new producers and new task claims before mutation, while allowing bounded acknowledgements for existing leases and operator recovery/inspection.
  • Fenced: reject ordinary mutations before they execute; preserve read-only inspection and explicit recovery access.
  • Keep authentication, role, namespace and protocol validation intact. Responses must not expose local paths or internal resource identifiers.
  • Reuse worker polling/backoff and task/attempt identities. Never describe an ambiguous completion as uncommitted, blindly replay application activity effects, or claim success after a storage rejection.
  • Pause new internal queue work while the resource is constrained. Document scheduler integration through the same observation rather than inventing another scheduler.

The storage operator owns authoritative measurement, reserve sizing, growth and recovery. This input is backpressure, not a replacement for native quotas, a byte reservation algorithm, or a guarantee against arbitrary write amplification between observations.

Acceptance

  • Implement the optional admission input, request classifications and observable reasons.
  • Test defaults, fresh normal/draining/fenced states, stale/malformed/missing snapshots and wrong resource identity.
  • Prove rejection precedes persistent mutation; completed history remains inspectable; existing request/task identities are preserved.
  • Verify PHP, Python and Rust poll behavior against pressure and recovery. Source-level contracts and published-package recovery passed. Rust external-payload readback was also fixed and published in sdk-rust#37 / 2.0.3.
  • Qualify concurrent producers and bounded outstanding completions against a real capacity-limited database, without deleting committed data. Native MySQL proof: 40 accepted producers, 16 draining refusals, eight completed leases, native 1114, same-volume restart/growth and unchanged data. The native test also passed on the published Server image; deployment-wide quota/reserve qualification remains operator-owned.
  • Publish the supported configuration/protocol and package changes after normal public checks. Server 2.3.0, PHP SDK 2.0.7, Python SDK 2.0.3 and Rust SDK 2.0.3 passed the published-tuple recovery experiment.

References: RabbitMQ disk alarms demonstrates why admission must precede disk exhaustion and why polling alone cannot guarantee an absolute bound; InnoDB error handling distinguishes statement rollback on full tablespaces from whole-transaction rollback.

Implementation merged in #132; published in Server 2.3.0. The reusable published-SDK experiment merged in #136 at 54556af636570f28b42144fd9f6bc340c938e824. Native full-capacity/growth and PHP/Python/Rust acknowledgement recovery, external-result consumption and fresh-process post-restart verification passed.

Admission remains opt-in. This completes the deployment-neutral Server contract, not any deployment's authoritative collector, all-writer reserve sizing, host quota, backup/restore or growth qualification. Operators must qualify those before enablement.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions