FrontendPro

105Implement an asynchronous dependency graph executor where tasks run only after their dependencies complete

hardAbout 60 minutesCodinggraphstopological-sortconcurrencypromises

Problem

Build systems, app start-up sequences and data loaders all run tasks that depend on other tasks. Implement runGraph(tasks, { concurrency = Infinity } = {}):

const results = await runGraph({
  config: { deps: [], run: () => loadConfig() },
  user: { deps: ["config"], run: ({ config }) => fetchUser(config.apiUrl) },
  flags: { deps: ["config"], run: ({ config }) => fetchFlags(config.apiUrl) },
  app: { deps: ["user", "flags"], run: ({ user, flags }) => startApp(user, flags) },
});
// user and flags run in parallel, after config, before app
  • Each task's run(depResults) receives an object with the results of its dependencies and may be async.
  • A task starts as soon as all its dependencies have finished; independent tasks run in parallel, up to concurrency at a time.
  • Before running anything, validate the graph: a dependency that does not exist throws Error('Unknown dependency "x" in task "y"'); a cycle throws an Error whose message contains the cycle path, for example Cycle detected: a -> b -> c -> a.
  • If a task fails, start no new tasks and reject with an error whose message names the task and includes the original message, with the original as cause. Tasks already running may finish.
  • Resolve with an object of every task's result.

Try it yourself

Write your solution, run it, then submit to check it against the tests.

solution.jsJavaScript

Press Run or ⌘ Enter to execute your code.

Step-by-step

Loop over every task's deps and throw for any name that is not a task. Doing this up front means a typo fails immediately instead of hanging forever.

Unlock the full solution

What's inside

  • Step-by-step
  • Approach
  • Solution
  • Complexity
  • Edge cases
  • Follow-up questions
  • Tests

Includes 2 code listings, 5 edge cases, 4 follow-up questions.

One-time payment by UPI, card or net banking. Launch price.

All 150 answersOne payment, yours forever