Files
stoatchat/crates/daemons/searchd/src/main.rs
Zomatree 553437e1df chore: update es code to lapin
Signed-off-by: Zomatree <me@zomatree.live>
2026-06-25 06:20:24 +01:00

207 lines
5.0 KiB
Rust

use lapin::{
options::{BasicConsumeOptions, ExchangeDeclareOptions, QueueBindOptions, QueueDeclareOptions},
types::{AMQPValue, FieldTable},
Channel, Connection, ConnectionProperties,
};
use log::info;
use revolt_config::{Settings, config, configure};
use revolt_database::{Database, DatabaseInfo, amqp::consumer::{Consumer, Delegate}};
use revolt_search::ElasticsearchClient;
use tokio::{signal::ctrl_c, spawn};
use std::{marker::PhantomData, sync::Arc};
mod consumers;
mod index;
async fn _main() {
configure!(api);
let config = config().await;
let db = DatabaseInfo::Auto.connect().await.unwrap();
let client = ElasticsearchClient::new(
&config.elasticsearch.host,
config.elasticsearch.port,
config.elasticsearch.api_key.clone(),
);
if std::env::var("REMAKE_MESSAGES_INDEX")
.as_deref()
.is_ok_and(|v| v == "1")
{
if client.delete_indexes().await.is_err() {
log::info!("Index does not existing, skipping.")
};
client.setup_indexes().await.unwrap();
};
let connection = Arc::new(
Connection::connect(
&format!(
"amqp://{}:{}@{}:{}",
&config.rabbit.username,
&config.rabbit.password,
&config.rabbit.host,
&config.rabbit.port,
),
ConnectionProperties::default(),
)
.await
.expect("Failed to connect to RabbitMQ"),
);
let mut channels = Vec::new();
channels.push(
make_queue_and_consume::<consumers::MessageConsumer>(
&client,
&db,
&connection,
&config,
&config.elasticsearch.message_queue,
)
.await,
);
channels.push(
make_queue_and_consume::<consumers::MessageEditConsumer>(
&client,
&db,
&connection,
&config,
&config.elasticsearch.message_edit_queue,
)
.await,
);
channels.push(
make_queue_and_consume::<consumers::MessageDeleteConsumer>(
&client,
&db,
&connection,
&config,
&config.elasticsearch.message_delete_queue,
)
.await,
);
channels.push(
make_queue_and_consume::<consumers::ChannelDeleteConsumer>(
&client,
&db,
&connection,
&config,
&config.elasticsearch.channel_delete_queue,
)
.await,
);
let mut task = None;
if std::env::var("INDEX_ALL_MESSAGES")
.as_deref()
.is_ok_and(|v| v == "1")
{
task = Some(spawn(index::index_existing_messages(db, client.clone())));
}
ctrl_c().await.unwrap();
for channel in channels {
let _ = channel.close(0, "close".into()).await;
}
if let Some(task) = task {
task.abort();
}
}
async fn make_queue_and_consume<F: Consumer<ElasticsearchClient>>(
client: &ElasticsearchClient,
db: &Database,
connection: &Arc<Connection>,
config: &Settings,
queue_name: &str,
) -> Arc<Channel> {
let channel = Arc::new(connection.create_channel().await.unwrap());
channel
.exchange_declare(
config.elasticsearch.exchange.clone().into(),
lapin::ExchangeKind::Direct,
ExchangeDeclareOptions {
durable: true,
..Default::default()
},
FieldTable::default(),
)
.await
.expect("Failed to declare exchange");
let mut table = FieldTable::default();
table.insert("x-queue-type".try_into().unwrap(), AMQPValue::LongString("quorum".into()));
let args = QueueDeclareOptions {
durable: true,
..Default::default()
};
channel
.queue_declare(queue_name.into(), args, table)
.await
.unwrap();
channel
.queue_bind(
queue_name.into(),
config.elasticsearch.exchange.clone().into(),
queue_name.into(),
QueueBindOptions::default(),
FieldTable::default(),
)
.await
.expect(
"This probably means the revolt.messages exchange does not exist in rabbitmq!",
);
let consumer = channel
.basic_consume(
queue_name.into(),
"".into(),
BasicConsumeOptions {
no_ack: true,
..Default::default()
},
FieldTable::default(),
)
.await
.unwrap();
info!(
"Consuming routing key {} as queue {}, tag {}",
queue_name,
queue_name,
consumer.tag()
);
let delegate = Delegate::new(
F::create(
db.clone(),
connection.clone(),
channel.clone(),
client.clone(),
)
.await,
);
consumer.set_delegate(delegate);
channel
}
#[tokio::main]
async fn main() {
_main().await
}