Skip to content

Your first task

You’ll write one Dart program that registers a task, starts a worker in the background, enqueues the task and prints its result. Then you’ll split it into a producer and a worker on Redis.

  • Dart SDK 3.3 or newer.
  • For the second half, a Redis server (docker run -d -p 6379:6379 redis:7-alpine).
Terminal window
dart create -t console queue_demo
cd queue_demo
dart pub add gisila_queue

Replace bin/queue_demo.dart:

import 'dart:async';
import 'package:gisila_queue/gisila_queue.dart';
Future<void> main() async {
final app = GisilaQueue(
broker: InMemoryBroker(),
backend: InMemoryResultBackend(),
);
// The type argument is the task's result type.
final add = app.task<int>(
'math.add',
(ctx) async => (ctx.arg(0) as int) + (ctx.arg(1) as int),
);
final worker = app.worker(concurrency: 4);
unawaited(worker.run()); // run() completes only after stop()
final r = await add.delay([2, 3]);
print('2 + 3 = ${await r.get()}');
final later = await add.applyAsync(
args: [10, 20],
countdown: const Duration(milliseconds: 500),
);
print('10 + 20 = ${await later.get()}');
await worker.stop();
await app.close();
}

delay returns an AsyncResult as soon as the message is enqueued; get() polls the backend until the worker has stored the result.

Producers and workers must register the same task names. Create lib/tasks.dart:

import 'package:gisila_queue/gisila_queue.dart';
class Tasks {
Tasks(GisilaQueue app)
: add = app.task<int>(
'math.add',
(ctx) async => (ctx.arg(0) as int) + (ctx.arg(1) as int),
maxRetries: 3,
);
final TaskRef<int> add;
}
GisilaQueue buildApp() => GisilaQueue.redis(namespace: 'demo');

bin/worker.dart:

import 'package:gisila_queue/gisila_queue_cli.dart';
import 'package:queue_demo/tasks.dart';
Future<void> main(List<String> argv) async {
final cli = WorkerCli.parse(argv);
if (cli.help) return print(WorkerCli.usage);
final app = cli.buildApp();
Tasks(app);
await cli.run(app); // stops cleanly on Ctrl-C
}

bin/producer.dart:

import 'package:queue_demo/tasks.dart';
Future<void> main() async {
final app = buildApp();
final tasks = Tasks(app);
final r = await tasks.add.delay([2, 3]);
print('enqueued ${r.id}');
print('result: ${await r.get(timeout: const Duration(seconds: 10))}');
await app.close();
}

Run the in-memory version first:

Terminal window
dart run bin/queue_demo.dart
[gisila_queue] INFO worker started: queues=default concurrency=4
2 + 3 = 5
...
10 + 20 = 30

Then the Redis version, in two terminals:

Terminal window
dart run bin/worker.dart --namespace=demo
dart run bin/producer.dart

The worker logs task math.add ✓ id=... and the producer prints result: 5.