FastPrepThread-Safe Task Storage and Worker Dispatch
Problem · Design

Thread-Safe Task Storage and Worker Dispatch

Learn this problem
MediumNuro logoNuroFULLTIMEONSITE INTERVIEW

Problem statement

Process a legal linearized history for a thread-safe task store. A task has one of three states: QUEUED, RUNNING, or COMPLETED. Each task keeps its original ADD order, and each worker holds at most one running task.

  • ["ADD", task] creates a unique queued task and produces task:QUEUED.
  • ["DISPATCH", worker] assigns the oldest-added task that is currently queued, producing task:RUNNING. It produces NONE when no task is queued.
  • ["COMPLETE", worker, task] marks that worker's running task completed, frees the worker, and produces task:COMPLETED. Repeating a completion for an already completed task is an idempotent no-op with the same output.
  • ["FAIL", worker, task] frees the worker, returns its task to QUEUED at the task's original ADD position, and produces task:QUEUED.
  • ["RELEASE", worker] behaves like FAIL for that worker's running task. For an idle worker it produces NONE.

Return one string per operation. The supplied sequence is one legal atomic order of concurrent calls; every operation observes the complete state left by its predecessor.

Function

taskWorkerHistory(operations: String[][]) → String[]

Examples

Example 1

operations = [["ADD","t1"],["ADD","t2"],["DISPATCH","w1"],["FAIL","w1","t1"],["DISPATCH","w2"],["COMPLETE","w2","t1"],["DISPATCH","w1"],["RELEASE","w1"]]return = ["t1:QUEUED","t2:QUEUED","t1:RUNNING","t1:QUEUED","t1:RUNNING","t1:COMPLETED","t2:RUNNING","t2:QUEUED"]

After failure, t1 keeps its earlier ADD position and is dispatched before t2.

Example 2

operations = [["DISPATCH","w0"],["RELEASE","w0"],["ADD","job"],["DISPATCH","w0"],["COMPLETE","w0","job"],["COMPLETE","w0","job"],["DISPATCH","w1"]]return = ["NONE","NONE","job:QUEUED","job:RUNNING","job:COMPLETED","job:COMPLETED","NONE"]

Empty dispatch and idle release return NONE. Completing the same finished task again is idempotent.

Constraints

  • 1 <= operations.length <= 100000.
  • Each task and worker ID has length from 1 through 32 and uses ASCII letters, digits, underscores, or hyphens.
  • Every ADD task ID is unique.
  • DISPATCH is called only for an idle worker.
  • FAIL names the exact task currently held by that worker.
  • COMPLETE names the exact task currently held by that worker or a task already completed by an earlier matching call.
  • The history is one complete linearization; no operation is partially visible.

More Nuro problems

drafts saved locally
public String[] taskWorkerHistory(String[][] operations) {
    // Write your solution here.
}
operations[["ADD","t1"],["ADD","t2"],["DISPATCH","w1"],["FAIL","w1","t1"],["DISPATCH","w2"],["COMPLETE","w2","t1"],["DISPATCH","w1"],["RELEASE","w1"]]
expected["t1:QUEUED", "t2:QUEUED", "t1:RUNNING", "t1:QUEUED", "t1:RUNNING", "t1:COMPLETED", "t2:RUNNING", "t2:QUEUED"]
checking account