Skip to main content

InboxTable

Trait InboxTable 

Source
pub trait InboxTable:
    Sized
    + Send
    + Sync
    + 'static {
    type Id: Clone + Debug + Send + Sync + 'static;
    type Table: Valid;

    const TABLE: Self::Table;

    // Required method
    fn id(&self) -> &Self::Id;
}
Expand description

A queue table described by hand.

A struct implements it with the table’s description in TABLE, built by InboxSpec, and the builder’s final type in type Table. The typed setters of the chain decide the type, and the compiler holds the chain to it, so the time types of the chain come from type Table.

§Examples

use chrono::{DateTime, Utc};
use std::time::Duration;

use ruststream_sqlx::dialect::Column;
use ruststream_sqlx::prelude::*;
use ruststream_sqlx::spec::{Attempt, Lease, Payload, ProcessedAt, RetryAfter};
use ruststream_sqlx::{AttemptRow, InboxSpec, InboxTable, PayloadRow};
use serde::Deserialize;
use sqlx::{Sqlite, SqlitePool};

#[derive(sqlx::FromRow)]
pub struct EmailJob {
    job_id: i64,
    attempt: i16,
    payload: Vec<u8>,
}

impl InboxTable for EmailJob {
    type Id = i64;
    type Table = InboxSpec<(
        Lease<DateTime<Utc>>,
        Payload,
        Attempt,
        RetryAfter<DateTime<Utc>>,
        ProcessedAt<DateTime<Utc>>,
    )>;
    const TABLE: Self::Table = InboxSpec::new("email_jobs", Column::new("job_id").generated())
        .group(Column::new("name"))
        .lease(Column::new("locked_until"))
        .payload(Column::new("payload"))
        .attempt(Column::new("attempt").generated())
        .retry_after(Column::new("retry_after"))
        .processed_at(Column::new("processed_at"));

    fn id(&self) -> &i64 {
        &self.job_id
    }
}

impl PayloadRow for EmailJob {
    type Column = Vec<u8>;

    fn payload(&self) -> &[u8] {
        &self.payload
    }
}

impl AttemptRow for EmailJob {
    type Attempt = i16;

    fn attempt(&self) -> &i16 {
        &self.attempt
    }
}

#[derive(Deserialize)]
struct Email {
    to: String,
}

// An address the mail server refuses comes back a minute later.
#[subscriber(InboxQueue::<EmailJob>::new("emails"))]
async fn send(email: &Email) -> HandlerOutcome {
    if email.to.ends_with("@example.com") {
        HandlerOutcome::ack()
    } else {
        HandlerOutcome::retry_after(Duration::from_secs(60))
    }
}

pub fn app(pool: SqlitePool) -> RustStream {
    RustStream::new(AppInfo::new("mailer", "1.0.0")).with_broker(
        SqlxBroker::<Sqlite>::new(pool),
        |b| {
            b.include(send);
        },
    )
}

Required Associated Constants§

Source

const TABLE: Self::Table

The table’s description.

Required Associated Types§

Source

type Id: Clone + Debug + Send + Sync + 'static

The type of the column that identifies a row.

Source

type Table: Valid

The table’s description as a type: InboxSpec<(..)>, listing the markers the chain of TABLE sets, in the order it sets them.

Required Methods§

Source

fn id(&self) -> &Self::Id

The row’s id.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§