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.
Prerequisites
Section titled “Prerequisites”- Dart SDK 3.3 or newer.
- For the second half, a Redis server (
docker run -d -p 6379:6379 redis:7-alpine).
1. Add the dependency
Section titled “1. Add the dependency”dart create -t console queue_democd queue_demodart pub add gisila_queue2. Register a task and run it in-process
Section titled “2. Register a task and run it in-process”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.
3. Move the tasks into shared code
Section titled “3. Move the tasks into shared code”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');4. Write a worker entrypoint
Section titled “4. Write a worker entrypoint”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}5. Write a producer
Section titled “5. Write a producer”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();}Verify it works
Section titled “Verify it works”Run the in-memory version first:
dart run bin/queue_demo.dart[gisila_queue] INFO worker started: queues=default concurrency=42 + 3 = 5...10 + 20 = 30Then the Redis version, in two terminals:
dart run bin/worker.dart --namespace=demodart run bin/producer.dartThe worker logs task math.add ✓ id=... and the producer prints result: 5.
Next steps
Section titled “Next steps”- Run workers in production.
- Handle retries and failures.
- Architecture explains what just happened.