Queues
The daemon consumes one or more cloud queues, listed in queues[] of <home>/config.json. Add, edit and delete them in
the admin UI's Queues tab or in the file.
Configuration#
Vendor (type) |
Settings | Credentials |
|---|---|---|
AWS SQS (aws-sqs) |
queueUrl, region, endpoint, waitTimeSeconds, maxMessages, visibilityTimeoutSeconds (default 120), maxConcurrency (default 4), extendedPayload.{enabled,deleteAfterAck}, deadLetterQueueUrl |
Default AWS credential chain: environment variables, ~/.aws, or an instance or task role |
Azure Service Bus (azure-servicebus) |
connectionString or fullyQualifiedNamespace (DefaultAzureCredential), queueName or topicName + subscriptionName, maxConcurrency, maxAutoLockRenewalDurationMs |
The connection string, or DefaultAzureCredential |
Google Pub/Sub (gcp-pubsub) |
projectId, subscription, maxConcurrency, claimCheck.{enabled,deleteAfterAck} |
Application Default Credentials |
Every queue also has a name, used in the admin UI and the logs. The example in
Install › Configuration file has one queue of each kind. ${ENV_VAR} references (like
"connectionString": "${AZURE_SERVICEBUS_CONNECTION_STRING}") are expanded at startup, so secrets can stay out of the file.
In the admin UI#
The Queues tab lists the queues in config.json with their live status. You can add, edit (including renaming) and
delete them there. A change is validated and written to config.json, and then the daemon restarts its queue consumers. You
don't need to restart the service.
The connection string can be written but not read back. The form shows it blank with "(set; leave blank to keep)". A
${ENV_VAR} reference is shown as it is, because it isn't a secret, and saving from the UI keeps the reference.
From the CLI: queues list (secrets masked) and queues remove <name>. Add or edit queues in the UI or in config.json. A
running daemon only picks up queues remove from the CLI when it restarts.
Without a valid license the queue consumers don't run and jobs wait in the queue (License).
Delivery semantics#
| Outcome | When | AWS SQS | Azure Service Bus | Pub/Sub |
|---|---|---|---|---|
| ack | Printed, or a duplicate jobId |
DeleteMessage, then delete the S3 payload | complete | ack, then delete the GCS payload |
| retry | Printer offline, timeout, spooler error (up to deadLetter.maxAttempts, default 5); printer disabled (paused; these attempts aren't counted); the same job already printing from another delivery |
visibility backoff: 30s × 2ⁿ, capped at 15 min | message held 5s × 2ⁿ (max 60s), then abandoned (DLQ after MaxDeliveryCount) |
nack after 5s × 2ⁿ (max 60s). Also set a subscription retry policy |
| dead-letter | Invalid JSON or schema, unknown printer, ad-hoc port not allowed, wrong printer kind, missing converter, corrupt document, or maxAttempts used up |
Saved to the daemon's local dead-letter list (<home>/dead-letter/) and acked from the queue |
same | same |
While a job runs:
- SQS: visibility is extended every half timeout.
- Azure: locks are renewed automatically.
- Pub/Sub: leases are extended by the client library.
Printed job ids are saved to disk, so a message redelivered after a crash or a lost ack isn't printed again (for
dedupe.ttlHours, default 24). The one exception: a crash after the printer accepted a job but before its id was saved
means that job prints again. If a multi-document job fails partway, the retry skips the documents that already printed
(tracked in memory, so this doesn't survive a restart).
Set visibilityTimeoutSeconds (SQS) or maxAutoLockRenewalDurationMs (Azure) higher than your slowest expected print or
Office conversion.
Dead letters#
A job that fails permanently (invalid message, unknown printer, unsupported conversion), or that fails
deadLetter.maxAttempts times (default 5), is saved on this machine in <home>/dead-letter/ and acked from the cloud queue.
It stays there until someone re-sends or deletes it. Nothing is re-sent automatically. Manage the list in the admin UI's
Dead letters tab or with the dead-letters CLI commands (Admin UI & CLI › Dead letters).
The list lives only on this machine and is lost with it: back up or monitor <home>/dead-letter/.
The vendor dead-letter queues#
The vendors' own dead-letter mechanisms are only a safety net: they catch messages the daemon never got to judge, for
example ones that crashed it, or a failed write to the local list. Keep them at a higher count than maxAttempts:
- SQS: a redrive policy with
maxReceiveCount>maxAttempts, and/ordeadLetterQueueUrl - Azure:
MaxDeliveryCount>maxAttempts - Pub/Sub: a dead-letter topic with
maxDeliveryAttempts>maxAttempts
Network and firewall#
The daemon only makes outbound connections. No inbound ports or public address are needed. Messages arrive over connections it keeps open:
| Vendor | Allow outbound to | Port |
|---|---|---|
| AWS SQS | sqs.<region>.amazonaws.com, and the payload bucket <bucket>.s3.<region>.amazonaws.com |
443 |
| Azure Service Bus | <namespace>.servicebus.windows.net (AMQP), login.microsoftonline.com (Azure AD only) |
5671, 443 |
| Google Pub/Sub | pubsub.googleapis.com (gRPC, HTTP/2), oauth2.googleapis.com, storage.googleapis.com |
443 |
- Pub/Sub: use a Pull subscription; push subscriptions need a public URL. Don't let a proxy downgrade
pubsub.googleapis.comto HTTP/1.1. - Not supported yet: Azure AMQP over WebSockets (443-only networks) and an outbound HTTP proxy for AWS/Azure. The admin UI's API tab has the same table.