Task Scheduler
Priority dispatch, worker quotas, and expiring leases
A lease token identifies one assignment attempt, not the task itself. After expiry a task returns to pending and may be reassigned to the same worker. Comparing only task and worker would let a stale completion finish the new attempt; compare the current token too.
struct LeaseIdentity {Int task_id;Int token;};
// expires_at <= now expires before complete() evaluates the token.Centralize time acceptance and expiration so dispatch, complete, get_task, and active agree at the exact boundary. Validate lease duration before moving time, because a rejected request must not expire unrelated assignments. A valid request returning no work still advances time. Capacity counts running tasks, and successful completion releases quota immediately. Priority ties use numeric IDs, preventing lexicographic mistakes once IDs exceed nine. Return task records by value so clients cannot change status or extend deadlines.
C++ contract conventions: numeric values use signed Int (long long); all inputs and intermediate arithmetic are within its representable range. Opt<T> means std::optional<T> and absence is std::nullopt; Vec<T> means std::vector<T>. Invalid documented arguments throw std::invalid_argument. Inputs passed by const reference remain caller owned. Returned containers and records own their contents. Calls use the declared C++ parameter types. Implicit conversions performed by the caller are outside the runtime validation contract. Unless a lesson states otherwise, string ordering is lexicographic over Unicode code points (Text) or UTF-8 identifiers (std::string).
Put it into practice
Implement the exercise in a full-screen workspace, then run its tests.