swift-server/swift-service-lifecycle

Tasks with dependsOn and topological sort of task start order

ktoso opened this issue · 1 comments

ktoso commented

The current way of defining lifecycle tasks is simple and works well for single or two frameworks or libraries adding tasks.

It gets complex if many libraries need to depend on some specific one thing, that some other library provides.

We could offer:

// Module X
    lifecycle.register(
        label: "service-y",
        dependsOn: "database", // ["database", "http-server"]
        start: .async { ... },
        shutdown: .sync { }
    )

// Module Y
    lifecycle.register(
        label: "service-y",
        dependsOn: "database", // ["database", "http-server"]
        start: .async { ... },
        shutdown: .sync { }
    )
// Main
// ModuleY(lifecycle)

    lifecycle.register(
        label: "database",
        start: .async { ... },
        shutdown: .sync { }
    )
ModuleX(lifecycle)
// ModuleY(lifecycle)

lifecycle.start()

^ it does not matter where I start ModuleY in "source order" and the dependencies will always be run in a predictable order.

and perform a Topological sort for starting the tasks in the right order.

This allows one library to start the "database" and other modules of a project to say i depend on "database" without having to specify more -- if the resolver notices there is no database task defined if can bail out. Otherwise, the order is made such that all tasks that depend on the "database" are spawned after it is ready.

ktoso commented

With structured concurrency this would be expressed differently I think, going to close.