Redis and RabbitMQ setup
You’ll configure the app for Redis with credentials and TLS, then for RabbitMQ with Redis for results, with matching namespaces in every process.
Prerequisites
Section titled “Prerequisites”- Redis 6+ (for ACL users) or any Redis for password-only auth.
- Optionally RabbitMQ 3.x with a vhost and user for the app.
1. Start Redis locally
Section titled “1. Start Redis locally”docker run -d --name redis -p 6379:6379 redis:7-alpine --requirepass secretexport REDIS_URL='redis://:secret@localhost:6379/0'2. Build the app from the URL
Section titled “2. Build the app from the URL”import 'dart:io';
import 'package:gisila_queue/gisila_queue.dart';
GisilaQueue buildApp() { final redis = RedisOptions.parseUrl(Platform.environment['REDIS_URL']!); return GisilaQueue.redis( namespace: 'shop', host: redis.host, port: redis.port, options: redis.options, );}rediss:// turns on TLS. For a private CA, pass a SecurityContext:
final ctx = SecurityContext(withTrustedRoots: false)..setTrustedCertificates('/etc/ssl/redis-ca.pem');final redis = RedisOptions.parseUrl(url, securityContext: ctx);3. Tune Redis options
Section titled “3. Tune Redis options”GisilaQueue.redis( namespace: 'shop', visibilityTimeout: const Duration(minutes: 2), // faster crash recovery resultTtl: const Duration(hours: 6), events: true, // for GisilaRose);Use a single Redis or a primary with replicas, not Redis Cluster. Turn on persistence (AOF) if queued work must survive a Redis restart.
4. Point the CLIs at it
Section titled “4. Point the CLIs at it”The worker, beat, inspect and rose binaries read REDIS_URL when --redis-url isn’t
given:
dart run bin/worker.dart --namespace=shopdart run gisila_queue:rose --namespace=shopRabbitMQ
Section titled “RabbitMQ”1. Start RabbitMQ and Redis
Section titled “1. Start RabbitMQ and Redis”docker run -d --name rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3-management2. Build the app
Section titled “2. Build the app”import 'package:gisila_queue/gisila_queue.dart';
GisilaQueue buildApp() => GisilaQueue( broker: RabbitBroker( host: 'localhost', username: 'guest', password: 'guest', virtualHost: '/', prefix: 'shop', prefetchCount: 32, ), backend: RedisResultBackend(host: 'localhost', prefix: 'shop'), controlChannel: RedisControlChannel(host: 'localhost', prefix: 'shop'), );Every component uses prefix: 'shop'; the constructor throws if they differ. Exchanges
and queues (shop.tasks, shop.queue.default, shop.delay.<ms>) are declared on first
use.
3. Write the worker by hand
Section titled “3. Write the worker by hand”WorkerCli builds a Redis app, so for RabbitMQ use CliArgs and installShutdownHooks
directly:
import 'package:gisila_queue/gisila_queue_cli.dart';import 'package:my_app/app.dart'; // buildApp()import 'package:my_app/tasks.dart'; // registerTasks()
Future<void> main(List<String> argv) async { final args = CliArgs.parse(argv); final app = buildApp(); registerTasks(app); final worker = app.worker( queues: args.stringList('queues') ?? ['default'], concurrency: args.intOr('concurrency', 8), ); installShutdownHooks(() => worker.stop(timeout: const Duration(seconds: 30))); await worker.run(); await app.close();}close() on the broker requeues anything it buffered or still had in flight.
Verify it works
Section titled “Verify it works”- Redis:
dart run gisila_queue:gisila_queue inspect --namespace=shopconnects and prints queue depths. - RabbitMQ: open
http://localhost:15672, findshop.queue.default, enqueue a task and watch its message count rise and fall.