27 releases (12 breaking)

0.13.3 Aug 31, 2024
0.13.2 Mar 10, 2024
0.12.0 Jan 3, 2024
0.10.0 Dec 28, 2023
0.1.0 Dec 11, 2021

#100 in Asynchronous

Download history 39/week @ 2024-08-21 216/week @ 2024-08-28 35/week @ 2024-09-04 69/week @ 2024-09-11 71/week @ 2024-09-18 72/week @ 2024-09-25 31/week @ 2024-10-02 52/week @ 2024-10-09 62/week @ 2024-10-16 74/week @ 2024-10-23 58/week @ 2024-10-30 22/week @ 2024-11-06 7/week @ 2024-11-13 31/week @ 2024-11-20 53/week @ 2024-11-27 68/week @ 2024-12-04

159 downloads per month
Used in 26 crates (4 directly)

MIT/Apache

285KB
6.5K SLoC

🧬 fn_graph

Crates.io docs.rs CI Coverage Status

Dynamically managed function graph execution.

This crate provides a FnGraph, where consumers can register a list of functions and their interdependencies. The graph can then return a stream of functions to iterate over either sequentially or concurrently. Any data dependencies required by the functions are guaranteed to not conflict according to borrowing rules.

There is additional flexibility that the type of functions is not limited to closures and functions, but any type that implements the FnRes and FnMeta traits.

Usage

Add the following to Cargo.toml

fn_graph = "0.13.3"

# Integrate with `fn_meta` / `interruptible` / `resman`
fn_graph = { version = "0.13.3", features = ["fn_meta"] }
fn_graph = { version = "0.13.3", features = ["interruptible"] }
fn_graph = { version = "0.13.3", features = ["resman"] }
fn_graph = { version = "0.13.3", features = ["fn_meta", "interruptible", "resman"] }

Rationale

Suppose there are three tasks, each represented by a function. Each function needs different data:

Function Data
f1 &a, &b
f2 &a, &b, &mut c
f3 &mut a, &b, &mut c

When scheduling parallel execution, it is valid to execute f1 and f2 in parallel, since data a and b are accessed immutably, and c is exclusively accessed by b. f3 cannot be executed in parallel with f1 or f2 as it requires exclusive access to both a and c.

For a small number of functions and data, manually writing code to schedule function execution is manageable. However, as the number of functions and data increases, so does its complexity, and it is desirable for this boilerplate to be managed by code.

Notes

The concept of a runtime managed data-dependency task graph is from shred; fn_graph's implementation has the following differences:

  • Different API ergonomics and flexibility trade-offs.

    • Takes functions and closures as input instead of System impls.

    • Parameters are detected from function signature instead of SystemData implementation, but with a limit of 8 parameters. (manual SystemData implementation has arbitrary limit)

    • Return type is type parameterized instead of ().

  • Instead of grouping functions by stages to manage data access conflicts, fn_graph keeps a dependency graph of logic and data dependencies, and executes functions when the preceding functions are complete.

    This allows for slightly less waiting time for subsequent functions with data dependencies, as each may begin once its predecessors finish, whereas a staged approach may contain other functions that are still executing that prevent functions in the next stage from beginning execution.

See Also

  • fn_meta: Returns metadata about a function at runtime.
  • interruptible: Support for interruptible streams.
  • resman: Runtime managed resource borrowing.
  • shred: Shared resource dispatcher.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Dependencies

~4–10MB
~92K SLoC