// AUTO-GENERATED by puerto. Edit puerto.toml, then run `puerto generate bootstrap`; add a
// consumer with `puerto generate consumer <name> --on <event_type>`.
{%- if consumers %}
use std::sync::Arc;
{% endif %}
{% for import in imports -%}
use {{ import }};
{% endfor -%}
{% if consumers %}
{% for m in modules -%}
use crate::consumers::{{ m.0 }}::{{ m.1 }};
{% endfor -%}
{% endif %}
/// The relay and one consumer per `[[consumer]]`, on the `db` transport: the relay hands each
/// event to `event_deliveries`, one row per consumer subscribed to its type.
pub async fn build_worker(config: WorkerConfig) -> Result<Loops, String> {
let database_url = std::env::var("DATABASE_URL")
.map_err(|_| "DATABASE_URL is not set — set it in .env (.env.example has one)".to_string())?;
let pool = infrastructure::db::create_postgres_pool(&database_url)
.await
.map_err(|e| format!("{e} — is the database up? `make docker-compose/up`"))?;
infrastructure::db::run_migrations(&pool, &infrastructure::db::MIGRATOR)
.await
.map_err(|e| e.to_string())?;
{%- if mails %}
// The mails sent on events (ADR-0020): one SMTP client and one sent log for all of them.
let mailer = Arc::new(
SmtpMailer::new(&MailConfig::from_env().map_err(|e| e.to_string())?)
.map_err(|e| e.to_string())?,
);
let sent_mails = Arc::new(PgSentMails::new(pool.clone()));
{%- endif %}
{% if consumers %}
let deliveries = PgDeliveries::new(pool.clone())
{%- for c in consumers %}
.route("{{ c.name }}", &[{{ c.events | join(sep=", ") }}])
{%- endfor %};
let dead_letters = Arc::new(PgDeadLetters::new(pool.clone()));
Ok(Loops::new(&config)
.relay(PgOutbox::new(pool.clone()), deliveries)
{%- for c in consumers %}
.consumer(
PgSubscription::new(pool.clone(), "{{ c.name }}"),
{{ c.handler }},
{% if loop.last %}dead_letters{% else %}dead_letters.clone(){% endif %},
)
{%- endfor %})
{%- else %}
Ok(Loops::new(&config).relay(PgOutbox::new(pool.clone()), PgDeliveries::new(pool)))
{%- endif %}
}