Basics / Async
Queues & Background Jobs
While building web applications, you may encounter tasks that take too long to complete during a typical web request, such as sending emails, generating reports, or hitting slow external APIs.
Archery provides an exceptional Background Job system powered by Dart Isolates that allows you to offload these tasks without blocking your main application thread.
Creating a Job
A Job is simply a class that mixes in Queueable and implements two methods: handle() to perform the work, and toJson() to serialize the job's payload.
import 'package:archery/archery/archery.dart';
class SendWelcomeEmail with Queueable {
final String emailAddress;
SendWelcomeEmail(this.emailAddress);
@override
Map<String, dynamic> toJson() => {
'emailAddress': emailAddress
};
@override
Future<dynamic> handle() async {
// Heavy lifting goes here!
// Example: await sesClient.sendEmail(to: emailAddress);
return 'Email sent successfully';
}
}
Dispatching Jobs
Once you have written your job, you can dispatch it from anywhere in your application, such as a controller route:
router.post('/register', (request) async {
// 1. Create the user
// 2. Dispatch the background job
await SendWelcomeEmail('jane@example.com').dispatch();
// 3. Quickly return a response to the user
return request.redirectHome();
});
When you call dispatch(), Archery automatically:
- Serializes the job into a hashed database record (using the
QueueJobmodel) ensuring the task persists. - Deduplicates pending jobs having identical payloads.
- Spawns an isolated worker thread specifically for this job type.
- Executes the job safely outside the main event loop.
- Updates the database status to
completeorfailed.
Inline Isolates
If you have a quick closure of heavy work and don't want to define an entirely new Queueable class, you can use QueueJob.inline:
router.get('/heavy-math', (request) async {
// Execute heavy computation without freezing the HTTP server
final result = await QueueJob.inline(() async {
return calculatePrimes();
});
return request.json({'result': result});
});