GithubHelp home page GithubHelp logo

graph-sequencer's Introduction

@pnpm/graph-sequencer

Sort items in a graph using a topological sort while resolving cycles with priority groups.

Say you have some sort of graph of dependencies: (using an adjacency list)

let graph = new Map([
  ["task-a", ["task-d"]], // task-a depends on task-d
  ["task-b", ["task-d", "task-a"]],
  ["task-c", ["task-d"]],
  ["task-d", ["task-a"]],
]);

You could run a topological sort on these items, but you'd still end up with cycles:

task-a -> task-d -> task-a

To resolve this you pass "priority groups" to graph-sequencer:

let groups = [
  ["task-d"], // higher priority
  ["task-a", "task-b", "task-c"], // lower priority
];

The result will be a chunked list of items sorted topologically and by the priority groups:

let chunks = [
  ["task-d"],
  ["task-a", "task-c"],
  ["task-b"]
];

You can then run all these items in order with maximum concurrency:

for (let chunk of chunks) {
  await Promise.all(chunk.map(task => exec(task)));
}

However, even with priority groups you can still accidentally create cycles of dependencies in your graph.

graph-sequencer will return a list of the unresolved cycles:

let cycles = [
  ["task-a", "task-b"] // task-a depends on task-b which depends on task-a
];

However, graph-sequencer will still return an "unsafe" set of chunks. When it comes across a cycle, it will add another chunk with the item with the fewest dependencies remaining which will often break cycles.

All together that looks like this:

const graphSequencer = require('@pnpm/graph-sequencer');

graphSequencer({
  graph: new Map([
    ["task-a", ["task-d"]], // task-a depends on task-d
    ["task-b", ["task-d", "task-a"]],
    ["task-c", ["task-d"]],
    ["task-d", ["task-a"]],
  ]);
  groups: [
    ["task-d"], // higher priority
    ["task-a", "task-b", "task-c"], // lower priority
  ],
})
// {
//   safe: true,
//   chunks: [["task-d"], ["task-a", "task-c"], ["task-b"]],
//   cycles: [],
// }

graph-sequencer's People

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.