startup_tasks
Maintained by akumaCN.
A lightweight Dart package for coordinating startup work as ordered, dependency-aware tasks.
Use it to split app initialization into stages, run independent tasks concurrently, enforce timeouts, retry recoverable work, and collect a startup report for logs or diagnostics. The package has no Flutter dependency, so it can be used from pure Dart packages, Flutter apps, command-line tools, or app-specific adapter layers.
Features
- Stage-based startup flow with
StartupStage. - Dependency-aware task scheduling inside each stage.
- Configurable per-stage concurrency.
- Critical, retry, continue, and skip-dependent failure policies.
- Per-task timeouts and cooperative cancellation.
- Shared typed startup context with
StartupKey<T>. - Structured
StartupReportoutput.
Getting started
Add the package to your pubspec.yaml:
dependencies:
startup_tasks: ^1.0.0
Import the public library:
import 'package:startup_tasks/startup_tasks.dart';
Usage
Define tasks by extending StartupTask, then pass them to StartupManager.
import 'package:startup_tasks/startup_tasks.dart';
const apiBaseUrlKey = StartupKey<String>('apiBaseUrl');
final class LoadConfigTask extends StartupTask {
const LoadConfigTask();
@override
String get id => 'app.load_config';
@override
StartupStage get stage => StartupStage.prepare;
@override
bool get critical => true;
@override
Future<void> run(StartupContext context) async {
context.write(apiBaseUrlKey, 'https://api.example.com');
}
}
final class RegisterServicesTask extends StartupTask {
const RegisterServicesTask();
@override
String get id => 'app.register_services';
@override
StartupStage get stage => StartupStage.business;
@override
List<String> get dependencies => const ['app.load_config'];
@override
Future<void> run(StartupContext context) async {
final apiBaseUrl = context.require(apiBaseUrlKey);
// 注册依赖 apiBaseUrl 的服务。
// Register services that depend on apiBaseUrl.
apiBaseUrl.length;
}
}
Future<void> main() async {
final manager = StartupManager(
tasks: const [
LoadConfigTask(),
RegisterServicesTask(),
],
);
final report = await manager.run();
print(report.formatSummary());
}
You can also run only part of the startup graph:
await manager.runUntil(StartupStage.business);
await manager.runAfter(StartupStage.business);
Failure handling
Each task can choose how failures affect the rest of startup:
@override
StartupFailurePolicy get failurePolicy => StartupFailurePolicy.retry;
@override
int get maxRetryCount => 2;
@override
Duration retryDelay(int retryCount) => Duration(milliseconds: 100 * retryCount);
By default, critical tasks fail startup and non-critical tasks record the failure while unrelated tasks continue.
License
MIT