batch 0.7.1 batch: ^0.7.1 copied to clipboard
A lightweight and powerful Job Scheduling Framework written in Dart. With this framework, you can easily develop a job scheduling and batch program in Dart.
A lightweight and powerful Job Scheduling Framework.
- 1. About
1. About #
The Batch.dart
specification is large and more detailed documentation can be found from Official Documents.
Also you can find detail examples of implementation at here.
1.1. Mission #
The goal of this project is to provide a high-performance and intuitive job scheduling framework in the Dart language ecosystem that anyone can use in the world.
And the development concept of this framework is "DRY", "KISS" and "YAGNI", which has been said in software engineering circles for a long time.
1.2. Features #
- Easy and intuitive job scheduling.
- Scheduling in Cron format provided as standard (Customizable).
- Powerful logging feature provided as standard (Customizable).
- Easily define parallel processes.
- No complicated configuration files.
- Supports conditional branching of jobs.
- Extensive callback functions are provided at each step.
- Supports skipping and retrying according to user defined conditions.
1.3. Basic Usage #
1.3.1. Install Library #
dart pub add batch
Note: In pub.dev, the automatic determination at the time of release of this library labels it as usable in Flutter, but it is not suitable by any stretch of the imagination.
1.3.2. Import #
The following import will provide all the materials for developing job scheduling using Batch.dart
.
import 'package:batch/batch.dart';
1.3.3. Basic Concept #
Batch.dart
represents the unit of scheduled processing as an Event
.
And Event
is composed of the following elements.
- Job - The largest unit.
- Step - The intermediate unit.
- Task - The smallest unit.
- Parallel - It's kind of Task but represents parallel processes.
You can see more information about Event
at Official Documents.
1.3.4. Configure Job Schedules #
1.3.4.1. Sequential Process
When defining a simple sequential process, all that is required is to define a class that extends Task
and implements the execute
method.
Example
import 'package:batch/batch.dart';
void main() => BatchApplication(),
..addJob(
// Scheduled to start every minute in Cron format
Job(name: 'Job', schedule: CronParser(value: '*/1 * * * *'))
// Step phase
..nextStep(Step(name: 'Step')
// Task phase
..nextTask(DoSomethingTask()
),
),
)
..run();
class DoSomethingTask extends Task<DoSomethingTask> {
@override
void execute(ExecutionContext) {
// Write your code here.
}
}
The above example is a very simple, and so you should refer to another document for more detailed specifications and implementation instructions.
You can see more details at Official Documents or example.
1.3.4.2. Parallel Process
Batch.dart
supports powerful parallel processing and is easy to define.
When defining parallel processing, all you have to do is just inherit from ParallelTask
and describe the process you want to parallelize in the invoke
method.
Example
import 'dart:async';
import 'package:batch/batch.dart';
void main() => BatchApplication(),
..addJob(
// Scheduled to start every minute in Cron format
Job(name: 'Job', schedule: CronParser(value: '*/1 * * * *'))
// Step phase
..nextStep(Step(name: 'Step')
// Parallel task phase
..nextParallel(
Parallel(
name: 'Parallel Tasks',
tasks: [
DoHeavyTask(),
DoHeavyTask(),
DoHeavyTask(),
DoHeavyTask(),
],
),
)
),
),
)
..run();
class DoHeavyTask extends ParallelTask<DoHeavyTask> {
@override
FutureOr<void> invoke() {
int i = 0;
while (i < 10000000000) {
i++;
}
}
}
1.3.5. Logging #
The Batch.dart
provides the following well-known logging features as a standard.
And the default log level is trace.
- trace
- debug
- info
- warn
- error
- fatal
The logging feature provided by Batch.dart
has extensive customization options. For more information, you can refer to the Official Documents describing logging on Batch.dart
.
1.3.5.1. On Sequential Process
It's very easy to use logging functions on sequential process.
The logging methods provided by the Batch.dart
can be used from any class that imports batch.dart
. So no need to instantiate any Loggers by yourself!
All you need to specify about logging in Batch.dart
is the configuration of the log before run BatchApplication
, and the Logger is provided safely under the lifecycle of the Batch.dart
.
Example
import 'package:batch/batch.dart';
class TestLogTask extends Task<TestLogTask> {
@override
void execute() {
trace('Test trace');
debug('Test debug');
info('Test info');
warn('Test warning');
error('Test error');
fatal('Test fatal');
// You can add "log." as a prefix.
log.trace('Test trace');
}
}
For example, if you run example code, you can get the following log output.
yyyy-MM-dd 19:25:10.575109 [info ] (_BatchApplication.run:129:11 ) - 🚀🚀🚀🚀🚀🚀🚀 The batch process has started! 🚀🚀🚀🚀🚀🚀🚀
yyyy-MM-dd 19:25:10.579318 [info ] (_BatchApplication.run:130:11 ) - Logger instance has completed loading
yyyy-MM-dd 19:25:10.580177 [info ] (_BootDiagnostics.run:32:9 ) - Batch application diagnostics have been started
yyyy-MM-dd 19:25:10.583234 [info ] (_BootDiagnostics.run:46:9 ) - Batch application diagnostics have been completed
yyyy-MM-dd 19:25:10.583344 [info ] (_BootDiagnostics.run:47:9 ) - Batch applications can be started securely
yyyy-MM-dd 19:25:10.585729 [info ] (JobScheduler.run:37:9 ) - Started Job scheduling on startup
yyyy-MM-dd 19:25:10.585921 [info ] (JobScheduler.run:38:9 ) - Detected 3 Jobs on the root
yyyy-MM-dd 19:25:10.586023 [info ] (JobScheduler.run:41:11 ) - Scheduling Job [name=Job1]
yyyy-MM-dd 19:25:10.595706 [info ] (JobScheduler.run:41:11 ) - Scheduling Job [name=Job2]
yyyy-MM-dd 19:25:10.597471 [info ] (JobScheduler.run:41:11 ) - Scheduling Job [name=Job4]
yyyy-MM-dd 19:25:10.597692 [info ] (JobScheduler.run:56:9 ) - Job scheduling has been completed and the batch application is now running
Note: The setup of the logger is done when executing the method
run
inBatchApplication
. If you want to use the logging feature outside the life cycle of thebatch
library, be sure to do so after executing therun
method of theBatchApplication
.
1.3.5.2. On Parallel Process
Parallel processing cannot directly use the convenient logging features described above. This is because parallel processing in the Dart language does not share any instances.
Instead, use the following methods in classes that extend ParallelTask
for parallel processing.
- sendMessageAsTrace
- sendMessageAsDebug
- sendMessageAsInfo
- sendMessageAsWarn
- sendMessageAsError
- sendMessageAsFatal
Example
class TestParallelTask extends ParallelTask<TestParallelTask> {
@override
FutureOr<void> invoke() {
super.sendMessageAsTrace('Trace');
super.sendMessageAsDebug('Debug');
super.sendMessageAsInfo('Info');
super.sendMessageAsWarn('Warn');
super.sendMessageAsError('Error');
super.sendMessageAsFatal('Fatal');
}
}
It should be noted that log output does not occur at the moment the above sendMessageAsX
method is used.
This is only a function that simulates log output in parallel processing, and all messages are output at once when all parallel processing included in Parallel
is completed.
And you can get the following log output from parallel processes.
yyyy-MM-dd 10:05:06.662561 [trace] (solatedLogMessage.output:36:13) - Received from the isolated thread [message=Trace]
yyyy-MM-dd 10:05:06.662666 [debug] (solatedLogMessage.output:39:13) - Received from the isolated thread [message=Debug]
yyyy-MM-dd 10:05:06.662760 [info ] (solatedLogMessage.output:42:13) - Received from the isolated thread [message=Info]
yyyy-MM-dd 10:05:06.662856 [warn ] (solatedLogMessage.output:45:13) - Received from the isolated thread [message=Warn]
yyyy-MM-dd 10:05:06.662947 [error] (solatedLogMessage.output:48:13) - Received from the isolated thread [message=Error]
yyyy-MM-dd 10:05:06.663039 [fatal] (solatedLogMessage.output:51:13) - Received from the isolated thread [message=Fatal]
1.3.6. Branch #
Batch.dart
supports conditional branching for each scheduled event (it's just called "Branch" in Batch.dart
).
Branch
is designed to be derived from each event, such as Job
, Step
, and Task
. There is no limit to the number of branches that can be set up, and a recursive nesting structure is also possible.
Creating a branch for each event is very easy.
To create branch
Step(name: 'Step')
// Assume that this task will change the branch status.
..nextTask(ChangeBranchStatusTask())
// Pass an event object to "to" argument that you want to execute when you enter this branch.
..branchOnSucceeded(to: Step(name: 'Step on succeeded')..nextTask(somethingTask))
..branchOnFailed(to: Step(name: 'Step on failed')..nextTask(somethingTask))
// Branches that are "branchOnCompleted" are always executed regardless of branch status.
..branchOnCompleted(to: Step(name: 'Step on completed'))..nextTask(somethingTask);
And the conditional branching of Batch.dart
is controlled by changing the BranchStatus
of each Execution
s that can be referenced from the ExecutionContext
.
The default branch status is "completed".
To manage branch
class ChangeBranchStatusTask extends Task<ChangeBranchStatusTask> {
@override
void execute(ExecutionContext context) {
// You can easily manage branch status through methods as below.
context.jobExecution!.branchToSucceeded();
context.stepExecution!.branchToFailed();
context.taskExecution!.branchToSucceeded();
}
}
1.4. Contribution #
If you would like to contribute to Batch.dart
, please create an issue or create a Pull Request.
Owner will respond to issues and review pull requests as quickly as possible.
1.5. Support #
The simplest way to show us your support is by giving the project a star at here.
And I'm always looking for sponsors to support this project. I'm not asking for royalties for use in providing this framework, but I do need support to continue ongoing open source development.
Sponsors can be individuals or corporations, and the amount is optional.
If you would like to sponsor me, please check my sponsorship page on GitHub or contact me at kato.shinya.dev@gmail.com.
1.6. License #
All resources of Batch.dart
is provided under the BSD-3
license.
Note: License notices in the source are strictly validated based on
.github/header-checker-lint.yml
. Please check header-checker-lint.yml for the permitted standards.
1.7. More Information #
Batch.dart
was designed and implemented by Kato Shinya.