For AI agents: the complete documentation index is available at https://a3s-lab.github.io/Boot/v0.1.4/en/llms.txt, the full documentation bundle is available at https://a3s-lab.github.io/Boot/v0.1.4/en/llms-full.txt, and this page is available as Markdown at https://a3s-lab.github.io/Boot/v0.1.4/en/protocols/queues-and-ilink.md.
  • English
  • v0.1.4
  • Queues and Weixin iLink

    Queues handle retryable background work. iLink connects an external messaging channel. Both integrate through providers and lifecycle, but their delivery semantics and deployment responsibilities are completely different.

    In-process queues

    With queue, QueueModule uses A3S Lane to provide workers, priorities, delays, retries, and processors.

    use a3s_boot::{QueueContext, QueueJob, QueueModule, QueueOptions, Result};
    
    let module = QueueModule::in_process_with_options(
        "mail-queue",
        QueueOptions::new().with_worker_count(4),
    )
    .processor("email.send", |job: QueueJob, context: QueueContext| async move {
        let email = job.data_as::<EmailJob>()?;
        let mailer = context.module_ref.get::<Mailer>()?;
        mailer.send(email).await
    });

    Queue provides typed serde JSON enqueue, processor registration, start, shutdown, job queries, failure queries, statistics, and clear. QueueJobOptions controls:

    • Priority and FIFO or LIFO ordering
    • Delay and processor timeout
    • Fixed and other QueueRetryPolicy strategies
    • Terminal retention
    • Caller-assigned idempotency keys
    • Deduplication ids and active keep-latest successors

    The in-process backend does not retain jobs across restart and is not shared with another process.

    Persistent PostgreSQL queues

    With queue-postgres, PostgresQueueBackend manages shared job tables and its migration ledger through A3S ORM.

    use std::time::Duration;
    use a3s_boot::{ModuleRef, PostgresQueueBackend, Queue, QueueOptions, Result};
    
    async fn open_queue(database_url: &str) -> Result<Queue> {
        let options = QueueOptions::new()
            .with_worker_count(4)
            .with_lease_duration(Duration::from_secs(30));
        let backend = PostgresQueueBackend::connect(
            database_url,
            "workflow",
            options,
        ).await?;
        let queue = Queue::new("workflow", backend);
        queue.start(ModuleRef::new()).await?;
        Ok(queue)
    }

    The backend claims ready jobs with PostgreSQL SKIP LOCKED, renews leases to retain live ownership, fences stale workers from completing jobs owned by a newer worker, and recovers expired leases after worker or process death.

    Boot v0.1.4 uses A3S ORM 0.2.0. The public queue API and lease, fencing, and recovery contracts remain the same. Internal claims use the ORM path available in that release.

    Give Boot Queue a dedicated PostgreSQL schema and point the database URL search path at it. The host creates the schema. Boot owns the queue tables and its own A3S ORM migration ledger inside it. Sharing a schema with Flow or application tables can make one component accept another component's migration history incorrectly.

    When retaining a backend handle, async services should use jobs_async, failures_async, stats_async, and clear_async for non-blocking diagnostics.

    Queue reliability

    Delivery is at least once. A processor timeout, lost worker, or crash after a business side effect but before completion can execute the same job again. Make business handlers idempotent with a job id, idempotency key, or domain-operation key.

    The PostgreSQL backend supports shared leasing, process-death recovery, retries, timeouts, retention, idempotency, and deduplication. Repeat jobs and Lane parent-child flow options are rejected explicitly and never degrade silently.

    Define these before production:

    • Queue capacity, worker concurrency, and poll interval
    • Lease duration with margin above maximum processing time
    • Retry count, backoff, and dead-letter or failure operations
    • Terminal retention and cleanup frequency
    • Schema backup, migration, and database-outage behavior
    • Shutdown order for stopping claims, renewing, and releasing leases

    With ilink, IlinkModule exports a typed IlinkClient:

    use a3s_boot::ilink::IlinkModule;
    
    let module = IlinkModule::weixin("A3S/0.10.1");

    The client owns QR login requests, redirects, authenticated headers, strict server URL validation, update polling, text replies, typing calls, and channel start and stop notifications. Sensitive authentication data uses constrained types and is zeroized where appropriate.

    Wire defaults are compatible with Tencent openclaw-weixin v2.4.6: iLink-App-Id: bot, bot_type=3, and packed client version 2.4.6. The product-specific bot_agent remains A3S/<version> so upstream diagnostics identify the caller correctly.

    Boot intentionally does not own:

    • Browser APIs and QR presentation UI
    • Credential persistence and secret storage
    • Owner authorization
    • Agent or session commands
    • Product reconnection, alerting, and operational policy

    These policies belong to the host application. Store credentials in a platform secret store and test logout, revocation, expiry, server-URL changes, poll timeouts, and duplicate updates. Bound reply and typing-call payloads and apply timeouts.