Skip to content

Messages and codec

Every enqueued call travels as a TaskMessage encoded as JSON. You rarely build one yourself; you see them in worker hooks, dead letters and custom brokers.

import 'package:gisila_queue/gisila_queue.dart';
class TaskMessage {
TaskMessage({
required String id,
required String task,
required String queue,
List<Object?> args = const [],
Map<String, Object?> kwargs = const {},
int retries = 0,
int maxRetries = 0,
DateTime? eta,
DateTime? createdAt,
int redeliveries = 0,
DateTime? expires,
List<Map<String, Object?>>? chain,
Map<String, Object?>? chord,
int requeues = 0,
Map<String, Object?>? deadLetter,
String? deliveryTag,
});
}

When to use: read it in a TaskObserver, when inspecting dead letters, or when implementing a Broker.

Field JSON key Description
id id Task id and result key.
task task Registered task name.
queue queue Destination queue.
args / kwargs args / kwargs Call arguments.
retries retries Application retries done so far.
maxRetries max_retries Retry ceiling.
eta eta Earliest run time (ISO-8601 UTC); omitted if none.
createdAt created_at When first produced.
redeliveries redeliveries Times a broker redelivered it because it was never acked.
expires expires Latest useful run time.
chain chain Remaining chain steps (ChainLink.toJson() maps).
chord chord Chord barrier (ChordBarrier.toJson()).
requeues requeues Times put back by RejectTask(requeue: true) or as an unknown task.
deadLetter dead_letter {reason, queue, at} when on a dead-letter queue.
deliveryTag not serialized Identifies one reservation so ack/touch act on exactly that delivery. Set by reserve.
Method Description
isDelayed(now) / isExpired(now) ETA in the future / expires in the past.
copyWith({...}) Copy with changes; clearEta, clearDeadLetter to null those fields. Drops deliveryTag.
retried(eta:) Copy with retries + 1 and the given ETA.
redelivered() Copy with redeliveries + 1.
withDeliveryTag(tag) Copy tagged for one delivery.
toJson() / TaskMessage.fromJson(json) Map form.
encode({codec}) / TaskMessage.decode(raw, {codec}) Wire string.
abstract class MessageCodec {
String encode(Map<String, Object?> json);
Map<String, Object?> decode(String raw);
}
class JsonMessageCodec implements MessageCodec { const JsonMessageCodec(); }
const MessageCodec defaultMessageCodec = JsonMessageCodec();

TaskMessage and StoredResult take an optional codec in encode/decode, but the brokers and backends always use defaultMessageCodec (JSON) and GisilaQueue has no codec setting. Treat the wire format as JSON.

void validateEncodable(String taskName, List<Object?> args, Map<String, Object?> kwargs,
{MessageCodec codec = defaultMessageCodec})

Throws UnencodableArgumentsException if the arguments don’t encode. GisilaQueue.send (and so delay/applyAsync) calls it before building the message, so the error points at your call site. Pass DateTime as toIso8601String(), enums as .name, and objects as toJson() maps.

await notify.delay([user.id, DateTime.now().toUtc().toIso8601String()]);

See also: Producer API, Errors.