Skip to content

Schedule delayed tasks

You’ll schedule a reminder for later, make sure a stale reminder is skipped, and make sure double submissions only schedule one.

  • An app with a result backend (needed for dedupeKey).
  • A worker running for the target queue.
import 'package:gisila_queue/gisila_queue.dart';
final app = GisilaQueue.redis(namespace: 'shop');
final remind = app.task<void>('carts.remind', (ctx) async {
final cartId = ctx.arg(0) as int;
await sendCartReminder(cartId);
return null;
});
await remind.applyAsync(args: [cartId], countdown: const Duration(hours: 2));
final tomorrow9am = DateTime.now().add(const Duration(days: 1));
await remind.applyAsync(
args: [cartId],
eta: DateTime(tomorrow9am.year, tomorrow9am.month, tomorrow9am.day, 9),
);

If both are given, countdown wins. The message is stored as scheduled until due. On Redis a due message is promoted about once a second, so expect up to a second of extra delay.

await remind.applyAsync(
args: [cartId],
countdown: const Duration(hours: 2),
expiresIn: const Duration(hours: 3),
);

If no worker picks it up before the expiry (workers were down, the queue was backed up), the worker records it as revoked (expired at ...) and does not run it.

dedupeKey is on app.send, which also takes eta and expires as absolute times:

final r = await app.send<void>(
'carts.remind',
args: [cartId],
eta: DateTime.now().add(const Duration(hours: 2)),
dedupeKey: 'cart-$cartId',
dedupeFor: const Duration(hours: 3),
);

A second call with the same key inside dedupeFor enqueues nothing and returns the first task’s AsyncResult (same id).

await app.resultFor<void>(r.id).revoke();

With a result backend, the revoke is stored, so the worker skips the task when it comes due even if it wasn’t running when you revoked.

final first = await app.send<void>('carts.remind', args: [7], dedupeKey: 'cart-7');
final second = await app.send<void>('carts.remind', args: [7], dedupeKey: 'cart-7');
print(first.id == second.id); // true
print(await first.state); // TaskState.pending (or scheduled with an eta)