Skip to content

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.

  • Redis 6+ (for ACL users) or any Redis for password-only auth.
  • Optionally RabbitMQ 3.x with a vhost and user for the app.
Terminal window
docker run -d --name redis -p 6379:6379 redis:7-alpine --requirepass secret
export REDIS_URL='redis://:secret@localhost:6379/0'
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);
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.

The worker, beat, inspect and rose binaries read REDIS_URL when --redis-url isn’t given:

Terminal window
dart run bin/worker.dart --namespace=shop
dart run gisila_queue:rose --namespace=shop
Terminal window
docker run -d --name rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3-management
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.

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.

  • Redis: dart run gisila_queue:gisila_queue inspect --namespace=shop connects and prints queue depths.
  • RabbitMQ: open http://localhost:15672, find shop.queue.default, enqueue a task and watch its message count rise and fall.