During a deployment, a backend should stop accepting new requests before the process is terminated. Existing requests must still be allowed to finish.
Design a DrainingBackendPool class:
DrainingBackendPool(int backendCount) creates backends in the ACTIVE state with zero active requests.int acquire() assigns a request to the least-loaded ACTIVE backend, increments its count, and returns its index. Return -1 when no backend is ACTIVE.void release(int backend) completes one request without allowing its count below zero.void startDrain(int backend) starts or repeats draining for one backend.String status(int backend) returns "ACTIVE", "DRAINING", or "REMOVED".
Lifecycle rules:
- Calling
startDrain on an active backend with outstanding requests changes it to DRAINING. - Calling it on an idle active backend changes it directly to
REMOVED. - A draining backend changes to
REMOVED when its last active request is released. - Draining and removed backends never receive new acquisitions.
- Repeated
startDrain calls do not change counts or reverse a state.
Among eligible backends with equal counts, select the smallest index.
Example 1:
Input:
Output:
Explanation: Backend 0 has two requests when draining begins. It remains available to those requests, but new requests consider only backends 1 and 2.
Example 2:
Input:
Output:
Explanation: Draining the only backend that can accept work makes new acquisition unavailable, but its one existing request is still released safely.
Constraints
1 <= backendCount <= 10^50 <= backend < backendCount- At most
10^5 calls are made to each method. - A release on a backend with zero active requests leaves its count at zero.