chore: update es code to lapin
Signed-off-by: Zomatree <me@zomatree.live>
This commit is contained in:
@@ -164,6 +164,10 @@ livekit-api = "=0.4.23"
|
|||||||
livekit-protocol = "=0.7.7"
|
livekit-protocol = "=0.7.7"
|
||||||
livekit-runtime = "0.4.0"
|
livekit-runtime = "0.4.0"
|
||||||
|
|
||||||
|
# Elasticsearch
|
||||||
|
elasticsearch = "9.1.0-alpha.1"
|
||||||
|
elasticsearch-dsl = "0.4"
|
||||||
|
|
||||||
# Other Utilities
|
# Other Utilities
|
||||||
once_cell = "1.9.0"
|
once_cell = "1.9.0"
|
||||||
config = "0.13.3"
|
config = "0.13.3"
|
||||||
@@ -203,3 +207,4 @@ revolt-permissions = { version = "0.13.7", path = "crates/core/permissions" }
|
|||||||
revolt-presence = { version = "0.13.7", path = "crates/core/presence" }
|
revolt-presence = { version = "0.13.7", path = "crates/core/presence" }
|
||||||
revolt-ratelimits = { version = "0.13.7", path = "crates/core/ratelimits" }
|
revolt-ratelimits = { version = "0.13.7", path = "crates/core/ratelimits" }
|
||||||
revolt-result = { version = "0.13.7", path = "crates/core/result" }
|
revolt-result = { version = "0.13.7", path = "crates/core/result" }
|
||||||
|
revolt-search = { version = "0.13.7", path = "crates/core/search" }
|
||||||
@@ -31,7 +31,7 @@ default = ["mongodb", "tokio-runtime", "tasks"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# Core
|
# Core
|
||||||
revolt-config = { workspace = true, features = ["report-macros"] }
|
revolt-config = { workspace = true, features = ["report-macros", "anyhow"] }
|
||||||
revolt-result = { workspace = true }
|
revolt-result = { workspace = true }
|
||||||
revolt-models = { workspace = true, features = ["validator"] }
|
revolt-models = { workspace = true, features = ["validator"] }
|
||||||
revolt-presence = { workspace = true }
|
revolt-presence = { workspace = true }
|
||||||
@@ -56,6 +56,7 @@ validator = { workspace = true, features = ["derive"] }
|
|||||||
isahc = { workspace = true, features = ["json"], optional = true }
|
isahc = { workspace = true, features = ["json"], optional = true }
|
||||||
base32 = { workspace = true }
|
base32 = { workspace = true }
|
||||||
sha1 = { workspace = true }
|
sha1 = { workspace = true }
|
||||||
|
anyhow = { workspace = true }
|
||||||
|
|
||||||
# Serialisation
|
# Serialisation
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
use std::{
|
use std::{
|
||||||
future::{ready, Future},
|
future::{Future, ready}, marker::PhantomData, pin::Pin, sync::Arc
|
||||||
pin::Pin,
|
|
||||||
sync::Arc,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
@@ -12,14 +10,15 @@ use lapin::{
|
|||||||
BasicProperties, Channel, Connection, ConsumerDelegate, Error as AMQPError,
|
BasicProperties, Channel, Connection, ConsumerDelegate, Error as AMQPError,
|
||||||
};
|
};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use revolt_database::Database;
|
use crate::Database;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait Consumer: Clone + Send + Sync + 'static {
|
pub trait Consumer<T: Clone = ()>: Clone + Send + Sync + 'static {
|
||||||
async fn create(
|
async fn create(
|
||||||
db: Database,
|
db: Database,
|
||||||
connection: Arc<Connection>,
|
connection: Arc<Connection>,
|
||||||
channel: Arc<Channel>,
|
channel: Arc<Channel>,
|
||||||
|
data: T,
|
||||||
) -> Self;
|
) -> Self;
|
||||||
fn channel(&self) -> &Arc<Channel>;
|
fn channel(&self) -> &Arc<Channel>;
|
||||||
async fn consume(&self, delivery: Delivery) -> Result<()>;
|
async fn consume(&self, delivery: Delivery) -> Result<()>;
|
||||||
@@ -65,9 +64,15 @@ pub trait Consumer: Clone + Send + Sync + 'static {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Delegate<C: Consumer>(pub C);
|
pub struct Delegate<C: Consumer<D>, D: Clone>(C, PhantomData<D>);
|
||||||
|
|
||||||
impl<C: Consumer> ConsumerDelegate for Delegate<C> {
|
impl<C: Consumer<D>, D: Clone> Delegate<C, D> {
|
||||||
|
pub fn new(consumer: C) -> Self {
|
||||||
|
Self(consumer, PhantomData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: Consumer<D>, D: Clone + Send + Sync> ConsumerDelegate for Delegate<C, D> {
|
||||||
fn on_new_delivery(
|
fn on_new_delivery(
|
||||||
&self,
|
&self,
|
||||||
delivery: DeliveryResult,
|
delivery: DeliveryResult,
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
#[allow(clippy::module_inception)]
|
#[allow(clippy::module_inception)]
|
||||||
pub mod amqp;
|
pub mod amqp;
|
||||||
|
pub mod consumer;
|
||||||
@@ -109,7 +109,7 @@ pub mod events;
|
|||||||
#[cfg(feature = "tasks")]
|
#[cfg(feature = "tasks")]
|
||||||
pub mod tasks;
|
pub mod tasks;
|
||||||
|
|
||||||
mod amqp;
|
pub mod amqp;
|
||||||
pub use amqp::amqp::AMQP;
|
pub use amqp::amqp::AMQP;
|
||||||
|
|
||||||
#[cfg(feature = "voice")]
|
#[cfg(feature = "voice")]
|
||||||
|
|||||||
@@ -882,13 +882,13 @@ impl User {
|
|||||||
/// - deletes owned bots, servers and messages
|
/// - deletes owned bots, servers and messages
|
||||||
/// - removes user from all groups
|
/// - removes user from all groups
|
||||||
/// - clears relationships
|
/// - clears relationships
|
||||||
pub async fn delete(&mut self, db: &Database) -> Result<()> {
|
pub async fn delete(&mut self, db: &Database, amqp: Option<&AMQP>) -> Result<()> {
|
||||||
for bot in db.fetch_bots_by_user(&self.id).await? {
|
for bot in db.fetch_bots_by_user(&self.id).await? {
|
||||||
bot.delete(db).await?;
|
bot.delete(db).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
for server in db.fetch_owned_servers(&self.id).await? {
|
for server in db.fetch_owned_servers(&self.id).await? {
|
||||||
server.delete(db).await?;
|
server.delete(db, amqp).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.remove_from_all_groups(db).await?;
|
self.remove_from_all_groups(db).await?;
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ pub mod permissions;
|
|||||||
pub mod reference;
|
pub mod reference;
|
||||||
pub mod shield;
|
pub mod shield;
|
||||||
pub mod test_fixtures;
|
pub mod test_fixtures;
|
||||||
pub mod chunked;
|
|
||||||
|
|
||||||
|
pub use chunked::ChunkedDatabaseGenerator;
|
||||||
pub use funcs::*;
|
pub use funcs::*;
|
||||||
pub use chunked::ChunkedDatabaseGenerator;
|
|
||||||
@@ -1,19 +1,19 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "revolt-search"
|
name = "revolt-search"
|
||||||
version = "0.12.0"
|
version = "0.13.7"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
revolt-config = { version = "0.12.0", path = "../config" }
|
revolt-config = { workspace = true }
|
||||||
revolt-database = { version = "0.12.0", path = "../database" }
|
revolt-database = { workspace = true }
|
||||||
revolt-models = { version = "0.12.0", path = "../models" }
|
revolt-models = { workspace = true }
|
||||||
elasticsearch = "9.1.0-alpha.1"
|
elasticsearch = { workspace = true }
|
||||||
serde_json = "1"
|
serde_json = { workspace = true }
|
||||||
ulid = "1.2.1"
|
ulid = { workspace = true }
|
||||||
iso8601-timestamp = { version = "0.2.10", features = ["serde", "bson"] }
|
iso8601-timestamp = { workspace = true, features = ["serde", "bson"] }
|
||||||
futures = "0.3.32"
|
futures = { workspace = true }
|
||||||
elasticsearch-dsl = "0.4"
|
elasticsearch-dsl = { workspace = true }
|
||||||
serde = "1"
|
serde = { workspace = true }
|
||||||
linkify = "0.10.0"
|
linkify = { workspace = true }
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use revolt_database::Database;
|
use revolt_database::{Database, AMQP};
|
||||||
use revolt_result::Result;
|
use revolt_result::Result;
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
|
|
||||||
pub async fn task(db: Database, _: revolt_database::AMQP) -> Result<()> {
|
pub async fn task(db: Database, amqp: AMQP) -> Result<()> {
|
||||||
loop {
|
loop {
|
||||||
let accounts = db.fetch_accounts_due_for_deletion().await?;
|
let accounts = db.fetch_accounts_due_for_deletion().await?;
|
||||||
let count = accounts.len();
|
let count = accounts.len();
|
||||||
@@ -12,7 +12,7 @@ pub async fn task(db: Database, _: revolt_database::AMQP) -> Result<()> {
|
|||||||
for mut account in accounts {
|
for mut account in accounts {
|
||||||
let mut user = db.fetch_user(&account.id).await?;
|
let mut user = db.fetch_user(&account.id).await?;
|
||||||
|
|
||||||
user.delete(&db).await?;
|
user.delete(&db, Some(&amqp)).await?;
|
||||||
account.mark_deleted(&db).await?;
|
account.mark_deleted(&db).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::utils::Consumer;
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use lapin::{message::Delivery, Channel, Connection};
|
use lapin::{message::Delivery, Channel, Connection};
|
||||||
use revolt_database::{events::rabbit::*, Database};
|
use revolt_database::{amqp::consumer::Consumer, events::rabbit::*, Database};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
@@ -16,11 +15,7 @@ pub struct AckConsumer {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Consumer for AckConsumer {
|
impl Consumer for AckConsumer {
|
||||||
async fn create(
|
async fn create(db: Database, connection: Arc<Connection>, channel: Arc<Channel>, _: ()) -> Self {
|
||||||
db: Database,
|
|
||||||
connection: Arc<Connection>,
|
|
||||||
channel: Arc<Channel>,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
db,
|
db,
|
||||||
connection,
|
connection,
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
use std::{collections::HashMap, sync::Arc};
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
use crate::utils::Consumer;
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use lapin::{message::Delivery, Channel, Connection};
|
use lapin::{message::Delivery, Channel, Connection};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use revolt_database::{events::rabbit::*, Database};
|
use revolt_database::{amqp::consumer::Consumer, events::rabbit::*, Database};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
@@ -17,11 +16,7 @@ pub struct DmCallConsumer {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Consumer for DmCallConsumer {
|
impl Consumer for DmCallConsumer {
|
||||||
async fn create(
|
async fn create(db: Database, connection: Arc<Connection>, channel: Arc<Channel>, _: ()) -> Self {
|
||||||
db: Database,
|
|
||||||
connection: Arc<Connection>,
|
|
||||||
channel: Arc<Channel>,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
db,
|
db,
|
||||||
connection,
|
connection,
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
use std::{collections::HashMap, sync::Arc};
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
use crate::utils::Consumer;
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use lapin::{message::Delivery, Channel, Connection};
|
use lapin::{message::Delivery, Channel, Connection};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use revolt_database::{events::rabbit::*, Database};
|
use revolt_database::{amqp::consumer::Consumer, events::rabbit::*, Database};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
@@ -17,11 +16,7 @@ pub struct FRAcceptedConsumer {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Consumer for FRAcceptedConsumer {
|
impl Consumer for FRAcceptedConsumer {
|
||||||
async fn create(
|
async fn create(db: Database, connection: Arc<Connection>, channel: Arc<Channel>, _: ()) -> Self {
|
||||||
db: Database,
|
|
||||||
connection: Arc<Connection>,
|
|
||||||
channel: Arc<Channel>,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
db,
|
db,
|
||||||
connection,
|
connection,
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
use std::{collections::HashMap, sync::Arc};
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
use crate::utils::Consumer;
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use lapin::{message::Delivery, Channel, Connection};
|
use lapin::{message::Delivery, Channel, Connection};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use revolt_database::{events::rabbit::*, Database};
|
use revolt_database::{amqp::consumer::Consumer, events::rabbit::*, Database};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
@@ -17,11 +16,7 @@ pub struct FRReceivedConsumer {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Consumer for FRReceivedConsumer {
|
impl Consumer for FRReceivedConsumer {
|
||||||
async fn create(
|
async fn create(db: Database, connection: Arc<Connection>, channel: Arc<Channel>, _: ()) -> Self {
|
||||||
db: Database,
|
|
||||||
connection: Arc<Connection>,
|
|
||||||
channel: Arc<Channel>,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
db,
|
db,
|
||||||
connection,
|
connection,
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
use std::{collections::HashMap, sync::Arc};
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
use crate::utils::Consumer;
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use lapin::{message::Delivery, Channel, Connection};
|
use lapin::{message::Delivery, Channel, Connection};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use revolt_database::{events::rabbit::*, Database};
|
use revolt_database::{amqp::consumer::Consumer, events::rabbit::*, Database};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
@@ -17,11 +16,7 @@ pub struct GenericConsumer {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Consumer for GenericConsumer {
|
impl Consumer for GenericConsumer {
|
||||||
async fn create(
|
async fn create(db: Database, connection: Arc<Connection>, channel: Arc<Channel>, _: ()) -> Self {
|
||||||
db: Database,
|
|
||||||
connection: Arc<Connection>,
|
|
||||||
channel: Arc<Channel>,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
db,
|
db,
|
||||||
connection,
|
connection,
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ use std::{
|
|||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::utils::{render_notification_content, Consumer};
|
use crate::utils::render_notification_content;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use lapin::{message::Delivery, Channel, Connection};
|
use lapin::{message::Delivery, Channel, Connection};
|
||||||
use revolt_database::{
|
use revolt_database::{
|
||||||
events::rabbit::*, util::bulk_permissions::BulkDatabasePermissionQuery, Database, Member,
|
amqp::consumer::Consumer, events::rabbit::*,
|
||||||
MessageFlagsValue,
|
util::bulk_permissions::BulkDatabasePermissionQuery, Database, Member, MessageFlagsValue,
|
||||||
};
|
};
|
||||||
use revolt_models::v0::{MessageFlags, PushNotification};
|
use revolt_models::v0::{MessageFlags, PushNotification};
|
||||||
use revolt_result::ToRevoltError;
|
use revolt_result::ToRevoltError;
|
||||||
@@ -29,11 +29,7 @@ impl MassMessageConsumer {
|
|||||||
push: &PushNotification,
|
push: &PushNotification,
|
||||||
users: &[String],
|
users: &[String],
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
if let Ok(sessions) = self
|
if let Ok(sessions) = self.db.fetch_sessions_with_subscription(users).await {
|
||||||
.db
|
|
||||||
.fetch_sessions_with_subscription(users)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
let config = revolt_config::config().await;
|
let config = revolt_config::config().await;
|
||||||
for session in sessions {
|
for session in sessions {
|
||||||
if let Some(sub) = session.subscription {
|
if let Some(sub) = session.subscription {
|
||||||
@@ -72,11 +68,7 @@ impl MassMessageConsumer {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Consumer for MassMessageConsumer {
|
impl Consumer for MassMessageConsumer {
|
||||||
async fn create(
|
async fn create(db: Database, connection: Arc<Connection>, channel: Arc<Channel>, _: ()) -> Self {
|
||||||
db: Database,
|
|
||||||
connection: Arc<Connection>,
|
|
||||||
channel: Arc<Channel>,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
db,
|
db,
|
||||||
connection,
|
connection,
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
use std::{collections::HashMap, sync::Arc};
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
use crate::utils::{render_notification_content, Consumer};
|
use crate::utils::render_notification_content;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use lapin::{message::Delivery, Channel, Connection};
|
use lapin::{message::Delivery, Channel, Connection};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use revolt_database::{events::rabbit::*, Database};
|
use revolt_database::{amqp::consumer::Consumer, events::rabbit::*, Database};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
@@ -17,11 +17,7 @@ pub struct MessageConsumer {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Consumer for MessageConsumer {
|
impl Consumer for MessageConsumer {
|
||||||
async fn create(
|
async fn create(db: Database, connection: Arc<Connection>, channel: Arc<Channel>, _: ()) -> Self {
|
||||||
db: Database,
|
|
||||||
connection: Arc<Connection>,
|
|
||||||
channel: Arc<Channel>,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
db,
|
db,
|
||||||
connection,
|
connection,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use std::{borrow::Cow, collections::BTreeMap, io::Cursor, sync::Arc};
|
use std::{borrow::Cow, collections::BTreeMap, io::Cursor, sync::Arc};
|
||||||
|
|
||||||
use crate::utils::Consumer;
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use base64::{
|
use base64::{
|
||||||
@@ -15,7 +14,7 @@ use revolt_a2::{
|
|||||||
},
|
},
|
||||||
Client, ClientConfig, Endpoint, Error, ErrorBody, ErrorReason, Priority, PushType, Response,
|
Client, ClientConfig, Endpoint, Error, ErrorBody, ErrorReason, Priority, PushType, Response,
|
||||||
};
|
};
|
||||||
use revolt_database::{events::rabbit::*, Database};
|
use revolt_database::{amqp::consumer::Consumer, events::rabbit::*, Database};
|
||||||
use revolt_models::v0::{Channel, Message, PushNotification};
|
use revolt_models::v0::{Channel, Message, PushNotification};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
@@ -123,11 +122,7 @@ impl ApnsOutboundConsumer {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Consumer for ApnsOutboundConsumer {
|
impl Consumer for ApnsOutboundConsumer {
|
||||||
async fn create(
|
async fn create(db: Database, connection: Arc<Connection>, channel: Arc<AMQPChannel>, _: ()) -> Self {
|
||||||
db: Database,
|
|
||||||
connection: Arc<Connection>,
|
|
||||||
channel: Arc<AMQPChannel>,
|
|
||||||
) -> Self {
|
|
||||||
let config = revolt_config::config().await;
|
let config = revolt_config::config().await;
|
||||||
|
|
||||||
if config.pushd.apn.pkcs8.is_empty()
|
if config.pushd.apn.pkcs8.is_empty()
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use std::{collections::HashMap, sync::Arc, time::Duration};
|
use std::{collections::HashMap, sync::Arc, time::Duration};
|
||||||
|
|
||||||
use crate::utils::Consumer;
|
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use fcm_v1::{
|
use fcm_v1::{
|
||||||
@@ -10,7 +9,7 @@ use fcm_v1::{
|
|||||||
};
|
};
|
||||||
use lapin::{message::Delivery, Channel as AMQPChannel, Connection};
|
use lapin::{message::Delivery, Channel as AMQPChannel, Connection};
|
||||||
use revolt_config::config;
|
use revolt_config::config;
|
||||||
use revolt_database::{events::rabbit::*, Database};
|
use revolt_database::{amqp::consumer::Consumer, events::rabbit::*, Database};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
/// Custom notification data
|
/// Custom notification data
|
||||||
@@ -126,11 +125,7 @@ pub struct FcmOutboundConsumer {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Consumer for FcmOutboundConsumer {
|
impl Consumer for FcmOutboundConsumer {
|
||||||
async fn create(
|
async fn create(db: Database, connection: Arc<Connection>, channel: Arc<AMQPChannel>, _: ()) -> Self {
|
||||||
db: Database,
|
|
||||||
connection: Arc<Connection>,
|
|
||||||
channel: Arc<AMQPChannel>,
|
|
||||||
) -> Self {
|
|
||||||
let config = revolt_config::config().await;
|
let config = revolt_config::config().await;
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
use std::{collections::HashMap, sync::Arc};
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
use crate::utils::Consumer;
|
|
||||||
|
|
||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{anyhow, bail, Result};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use base64::{
|
use base64::{
|
||||||
@@ -9,7 +7,9 @@ use base64::{
|
|||||||
Engine as _,
|
Engine as _,
|
||||||
};
|
};
|
||||||
use lapin::{message::Delivery, Channel as AMQPChannel, Connection};
|
use lapin::{message::Delivery, Channel as AMQPChannel, Connection};
|
||||||
use revolt_database::{events::rabbit::*, util::format_display_name, Database};
|
use revolt_database::{
|
||||||
|
amqp::consumer::Consumer, events::rabbit::*, util::format_display_name, Database,
|
||||||
|
};
|
||||||
use web_push::{
|
use web_push::{
|
||||||
ContentEncoding, IsahcWebPushClient, SubscriptionInfo, SubscriptionKeys, VapidSignatureBuilder,
|
ContentEncoding, IsahcWebPushClient, SubscriptionInfo, SubscriptionKeys, VapidSignatureBuilder,
|
||||||
WebPushClient, WebPushError, WebPushMessageBuilder,
|
WebPushClient, WebPushError, WebPushMessageBuilder,
|
||||||
@@ -27,11 +27,7 @@ pub struct VapidOutboundConsumer {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Consumer for VapidOutboundConsumer {
|
impl Consumer for VapidOutboundConsumer {
|
||||||
async fn create(
|
async fn create(db: Database, connection: Arc<Connection>, channel: Arc<AMQPChannel>, _: ()) -> Self {
|
||||||
db: Database,
|
|
||||||
connection: Arc<Connection>,
|
|
||||||
channel: Arc<AMQPChannel>,
|
|
||||||
) -> Self {
|
|
||||||
let config = revolt_config::config().await;
|
let config = revolt_config::config().await;
|
||||||
|
|
||||||
if config.pushd.vapid.private_key.is_empty() || config.pushd.vapid.public_key.is_empty() {
|
if config.pushd.vapid.private_key.is_empty() || config.pushd.vapid.public_key.is_empty() {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use lapin::{
|
|||||||
Channel, Connection, ConnectionProperties,
|
Channel, Connection, ConnectionProperties,
|
||||||
};
|
};
|
||||||
use revolt_config::{config, Settings};
|
use revolt_config::{config, Settings};
|
||||||
use revolt_database::Database;
|
use revolt_database::{Database, amqp::consumer::{Consumer, Delegate}};
|
||||||
use tokio::signal::ctrl_c;
|
use tokio::signal::ctrl_c;
|
||||||
|
|
||||||
mod consumers;
|
mod consumers;
|
||||||
@@ -23,8 +23,6 @@ use consumers::{
|
|||||||
outbound::{apn::ApnsOutboundConsumer, fcm::FcmOutboundConsumer, vapid::VapidOutboundConsumer},
|
outbound::{apn::ApnsOutboundConsumer, fcm::FcmOutboundConsumer, vapid::VapidOutboundConsumer},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::utils::{Consumer, Delegate};
|
|
||||||
|
|
||||||
#[tokio::main(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::main(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
// Configure logging and environment
|
// Configure logging and environment
|
||||||
@@ -275,11 +273,12 @@ where
|
|||||||
consumer.tag()
|
consumer.tag()
|
||||||
);
|
);
|
||||||
|
|
||||||
let delegate = Delegate(
|
let delegate = Delegate::new(
|
||||||
F::create(
|
F::create(
|
||||||
db.clone(),
|
db.clone(),
|
||||||
connection.clone(),
|
connection.clone(),
|
||||||
channel.clone(),
|
channel.clone(),
|
||||||
|
()
|
||||||
)
|
)
|
||||||
.await,
|
.await,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
mod renderer;
|
mod renderer;
|
||||||
mod consumer;
|
|
||||||
|
|
||||||
pub use renderer::render_notification_content;
|
pub use renderer::render_notification_content;
|
||||||
pub use consumer::{Consumer, Delegate};
|
|
||||||
@@ -1,16 +1,17 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "revolt-searchd"
|
name = "revolt-searchd"
|
||||||
version = "0.12.0"
|
version = "0.13.7"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "AGPL-3.0-or-later"
|
license = "AGPL-3.0-or-later"
|
||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tokio = { version = "1.50.0", features = ["macros"] }
|
tokio = { workspace = true, features = ["macros"] }
|
||||||
revolt-database = { version = "0.12.0", path = "../../core/database" }
|
revolt-database = { workspace = true }
|
||||||
revolt-config = { version = "0.12.0", path = "../../core/config" }
|
revolt-config = { workspace = true }
|
||||||
revolt-search = { version = "0.12.0", path = "../../core/search" }
|
revolt-search = { workspace = true }
|
||||||
amqprs = "1.7.0"
|
lapin = { workspace = true }
|
||||||
async-trait = "0.1.89"
|
async-trait = { workspace = true }
|
||||||
log = "0.4.29"
|
log = { workspace = true }
|
||||||
serde_json = "1"
|
serde_json = { workspace = true }
|
||||||
|
anyhow = { workspace = true }
|
||||||
@@ -1,34 +1,37 @@
|
|||||||
use amqprs::{
|
use std::sync::Arc;
|
||||||
BasicProperties, Deliver,
|
|
||||||
channel::{BasicAckArguments, BasicRejectArguments, Channel},
|
use lapin::{Channel, Connection, message::Delivery, options::{BasicAckOptions, BasicRejectOptions}};
|
||||||
consumer::AsyncConsumer,
|
|
||||||
};
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use revolt_database::{Database, events::rabbit::ChannelDeletePayload};
|
use revolt_database::{Database, events::rabbit::ChannelDeletePayload, amqp::consumer::Consumer};
|
||||||
use revolt_search::ElasticsearchClient;
|
use revolt_search::ElasticsearchClient;
|
||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct ChannelDeleteConsumer {
|
pub struct ChannelDeleteConsumer {
|
||||||
client: ElasticsearchClient,
|
client: ElasticsearchClient,
|
||||||
database: Database,
|
database: Database,
|
||||||
}
|
connection: Arc<Connection>,
|
||||||
|
channel: Arc<Channel>,
|
||||||
impl ChannelDeleteConsumer {
|
|
||||||
pub fn new(client: ElasticsearchClient, database: Database) -> Self {
|
|
||||||
Self { client, database }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl AsyncConsumer for ChannelDeleteConsumer {
|
impl Consumer<ElasticsearchClient> for ChannelDeleteConsumer {
|
||||||
async fn consume(
|
async fn create(database: Database, connection: Arc<Connection>, channel: Arc<Channel>, client: ElasticsearchClient) -> Self {
|
||||||
&mut self,
|
Self {
|
||||||
channel: &Channel,
|
client,
|
||||||
deliver: Deliver,
|
database,
|
||||||
_basic_properties: BasicProperties,
|
connection,
|
||||||
content: Vec<u8>,
|
channel,
|
||||||
) {
|
}
|
||||||
let payload = serde_json::from_slice::<ChannelDeletePayload>(&content)
|
}
|
||||||
|
|
||||||
|
fn channel(&self) -> &Arc<Channel> {
|
||||||
|
&self.channel
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn consume(&self, delivery: Delivery) -> Result<()> {
|
||||||
|
let payload = serde_json::from_slice::<ChannelDeletePayload>(&delivery.data)
|
||||||
.expect("Failed to decode message");
|
.expect("Failed to decode message");
|
||||||
log::debug!("Received channel delete {payload:?}");
|
log::debug!("Received channel delete {payload:?}");
|
||||||
|
|
||||||
@@ -38,15 +41,19 @@ impl AsyncConsumer for ChannelDeleteConsumer {
|
|||||||
.await
|
.await
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
channel
|
self.channel
|
||||||
.basic_ack(BasicAckArguments::new(deliver.delivery_tag(), false))
|
.basic_ack(delivery.delivery_tag, BasicAckOptions::default())
|
||||||
.await
|
.await
|
||||||
.expect("Failed to ack");
|
.expect("Failed to ack");
|
||||||
} else {
|
} else {
|
||||||
channel
|
self.channel
|
||||||
.basic_reject(BasicRejectArguments::new(deliver.delivery_tag(), true))
|
.basic_reject(delivery.delivery_tag, BasicRejectOptions {
|
||||||
|
requeue: true,
|
||||||
|
})
|
||||||
.await
|
.await
|
||||||
.expect("Failed to reject");
|
.expect("Failed to reject");
|
||||||
}
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +1,38 @@
|
|||||||
use amqprs::{
|
use std::sync::Arc;
|
||||||
BasicProperties, Deliver,
|
|
||||||
channel::{BasicAckArguments, BasicRejectArguments, Channel},
|
|
||||||
consumer::AsyncConsumer,
|
|
||||||
};
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use revolt_database::{Database, events::rabbit::MessageCreatePayload};
|
|
||||||
use revolt_search::ElasticsearchClient;
|
|
||||||
|
|
||||||
|
use lapin::{Channel, Connection, message::Delivery, options::{BasicAckOptions, BasicRejectOptions}};
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use revolt_database::{Database, events::rabbit::MessageCreatePayload, amqp::consumer::Consumer};
|
||||||
|
use revolt_search::ElasticsearchClient;
|
||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct MessageConsumer {
|
pub struct MessageConsumer {
|
||||||
client: ElasticsearchClient,
|
client: ElasticsearchClient,
|
||||||
database: Database,
|
database: Database,
|
||||||
}
|
connection: Arc<Connection>,
|
||||||
|
channel: Arc<Channel>,
|
||||||
impl MessageConsumer {
|
|
||||||
pub fn new(client: ElasticsearchClient, database: Database) -> Self {
|
|
||||||
Self { client, database }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl AsyncConsumer for MessageConsumer {
|
impl Consumer<ElasticsearchClient> for MessageConsumer {
|
||||||
async fn consume(
|
async fn create(database: Database, connection: Arc<Connection>, channel: Arc<Channel>, client: ElasticsearchClient) -> Self {
|
||||||
&mut self,
|
Self {
|
||||||
channel: &Channel,
|
client,
|
||||||
deliver: Deliver,
|
database,
|
||||||
_basic_properties: BasicProperties,
|
connection,
|
||||||
content: Vec<u8>,
|
channel,
|
||||||
) {
|
}
|
||||||
let payload = serde_json::from_slice::<MessageCreatePayload>(&content)
|
}
|
||||||
|
|
||||||
|
fn channel(&self) -> &Arc<Channel> {
|
||||||
|
&self.channel
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn consume(&self, delivery: Delivery) -> Result<()> {
|
||||||
|
let payload = serde_json::from_slice::<MessageCreatePayload>(&delivery.data)
|
||||||
.expect("Failed to decode message");
|
.expect("Failed to decode message");
|
||||||
log::debug!("Received message {payload:?}");
|
log::debug!("Received message {payload:?}");
|
||||||
|
|
||||||
@@ -37,15 +42,19 @@ impl AsyncConsumer for MessageConsumer {
|
|||||||
.await
|
.await
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
channel
|
self.channel
|
||||||
.basic_ack(BasicAckArguments::new(deliver.delivery_tag(), false))
|
.basic_ack(delivery.delivery_tag, BasicAckOptions::default())
|
||||||
.await
|
.await
|
||||||
.expect("Failed to ack");
|
.expect("Failed to ack");
|
||||||
} else {
|
} else {
|
||||||
channel
|
self.channel
|
||||||
.basic_reject(BasicRejectArguments::new(deliver.delivery_tag(), true))
|
.basic_reject(delivery.delivery_tag, BasicRejectOptions {
|
||||||
|
requeue: true,
|
||||||
|
})
|
||||||
.await
|
.await
|
||||||
.expect("Failed to reject");
|
.expect("Failed to reject");
|
||||||
}
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +1,39 @@
|
|||||||
use amqprs::{
|
use std::sync::Arc;
|
||||||
BasicProperties, Deliver,
|
|
||||||
channel::{BasicAckArguments, BasicRejectArguments, Channel},
|
use lapin::{Channel, Connection, message::Delivery, options::{BasicAckOptions, BasicRejectOptions}};
|
||||||
consumer::AsyncConsumer,
|
|
||||||
};
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use revolt_database::{Database, events::rabbit::MessageDeletePayload};
|
use revolt_database::{Database, events::rabbit::MessageDeletePayload, amqp::consumer::Consumer};
|
||||||
use revolt_search::ElasticsearchClient;
|
use revolt_search::ElasticsearchClient;
|
||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct MessageDeleteConsumer {
|
pub struct MessageDeleteConsumer {
|
||||||
client: ElasticsearchClient,
|
client: ElasticsearchClient,
|
||||||
database: Database,
|
database: Database,
|
||||||
|
connection: Arc<Connection>,
|
||||||
|
channel: Arc<Channel>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MessageDeleteConsumer {
|
|
||||||
pub fn new(client: ElasticsearchClient, database: Database) -> Self {
|
|
||||||
Self { client, database }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl AsyncConsumer for MessageDeleteConsumer {
|
impl Consumer<ElasticsearchClient> for MessageDeleteConsumer {
|
||||||
async fn consume(
|
async fn create(database: Database, connection: Arc<Connection>, channel: Arc<Channel>, client: ElasticsearchClient) -> Self {
|
||||||
&mut self,
|
Self {
|
||||||
channel: &Channel,
|
client,
|
||||||
deliver: Deliver,
|
database,
|
||||||
_basic_properties: BasicProperties,
|
connection,
|
||||||
content: Vec<u8>,
|
channel,
|
||||||
) {
|
}
|
||||||
let payload = serde_json::from_slice::<MessageDeletePayload>(&content)
|
}
|
||||||
|
|
||||||
|
fn channel(&self) -> &Arc<Channel> {
|
||||||
|
&self.channel
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn consume(&self, delivery: Delivery) -> Result<()> {
|
||||||
|
let payload = serde_json::from_slice::<MessageDeletePayload>(&delivery.data)
|
||||||
.expect("Failed to decode message");
|
.expect("Failed to decode message");
|
||||||
log::debug!("Received message delete {payload:?}");
|
log::debug!("Received message delete {payload:?}");
|
||||||
|
|
||||||
@@ -38,15 +43,19 @@ impl AsyncConsumer for MessageDeleteConsumer {
|
|||||||
.await
|
.await
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
channel
|
self.channel
|
||||||
.basic_ack(BasicAckArguments::new(deliver.delivery_tag(), false))
|
.basic_ack(delivery.delivery_tag, BasicAckOptions::default())
|
||||||
.await
|
.await
|
||||||
.expect("Failed to ack");
|
.expect("Failed to ack");
|
||||||
} else {
|
} else {
|
||||||
channel
|
self.channel
|
||||||
.basic_reject(BasicRejectArguments::new(deliver.delivery_tag(), true))
|
.basic_reject(delivery.delivery_tag, BasicRejectOptions {
|
||||||
|
requeue: true,
|
||||||
|
})
|
||||||
.await
|
.await
|
||||||
.expect("Failed to reject");
|
.expect("Failed to reject");
|
||||||
}
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +1,38 @@
|
|||||||
use amqprs::{
|
use std::sync::Arc;
|
||||||
BasicProperties, Deliver,
|
|
||||||
channel::{BasicAckArguments, BasicRejectArguments, Channel},
|
|
||||||
consumer::AsyncConsumer,
|
|
||||||
};
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use revolt_database::{Database, events::rabbit::MessageEditPayload};
|
|
||||||
use revolt_search::ElasticsearchClient;
|
|
||||||
|
|
||||||
|
|
||||||
|
use lapin::{Channel, Connection, message::Delivery, options::{BasicAckOptions, BasicRejectOptions}};
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use revolt_database::{Database, events::rabbit::MessageEditPayload, amqp::consumer::Consumer};
|
||||||
|
use revolt_search::ElasticsearchClient;
|
||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct MessageEditConsumer {
|
pub struct MessageEditConsumer {
|
||||||
client: ElasticsearchClient,
|
client: ElasticsearchClient,
|
||||||
database: Database,
|
database: Database,
|
||||||
}
|
connection: Arc<Connection>,
|
||||||
|
channel: Arc<Channel>,
|
||||||
impl MessageEditConsumer {
|
|
||||||
pub fn new(client: ElasticsearchClient, database: Database) -> Self {
|
|
||||||
Self { client, database }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl AsyncConsumer for MessageEditConsumer {
|
impl Consumer<ElasticsearchClient> for MessageEditConsumer {
|
||||||
async fn consume(
|
async fn create(database: Database, connection: Arc<Connection>, channel: Arc<Channel>, client: ElasticsearchClient) -> Self {
|
||||||
&mut self,
|
Self {
|
||||||
channel: &Channel,
|
client,
|
||||||
deliver: Deliver,
|
database,
|
||||||
_basic_properties: BasicProperties,
|
connection,
|
||||||
content: Vec<u8>,
|
channel,
|
||||||
) {
|
}
|
||||||
let payload = serde_json::from_slice::<MessageEditPayload>(&content)
|
}
|
||||||
|
|
||||||
|
fn channel(&self) -> &Arc<Channel> {
|
||||||
|
&self.channel
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn consume(&self, delivery: Delivery) -> Result<()> {
|
||||||
|
let payload = serde_json::from_slice::<MessageEditPayload>(&delivery.data)
|
||||||
.expect("Failed to decode message");
|
.expect("Failed to decode message");
|
||||||
log::debug!("Received edit message {payload:?}");
|
log::debug!("Received edit message {payload:?}");
|
||||||
|
|
||||||
@@ -37,15 +42,19 @@ impl AsyncConsumer for MessageEditConsumer {
|
|||||||
.await
|
.await
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
channel
|
self.channel
|
||||||
.basic_ack(BasicAckArguments::new(deliver.delivery_tag(), false))
|
.basic_ack(delivery.delivery_tag, BasicAckOptions::default())
|
||||||
.await
|
.await
|
||||||
.expect("Failed to ack");
|
.expect("Failed to ack");
|
||||||
} else {
|
} else {
|
||||||
channel
|
self.channel
|
||||||
.basic_reject(BasicRejectArguments::new(deliver.delivery_tag(), true))
|
.basic_reject(delivery.delivery_tag, BasicRejectOptions {
|
||||||
|
requeue: true,
|
||||||
|
})
|
||||||
.await
|
.await
|
||||||
.expect("Failed to reject");
|
.expect("Failed to reject");
|
||||||
}
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
use amqprs::{
|
use lapin::{
|
||||||
FieldTable,
|
options::{BasicConsumeOptions, ExchangeDeclareOptions, QueueBindOptions, QueueDeclareOptions},
|
||||||
channel::{
|
types::{AMQPValue, FieldTable},
|
||||||
BasicConsumeArguments, Channel, ExchangeDeclareArguments, QueueBindArguments,
|
Channel, Connection, ConnectionProperties,
|
||||||
QueueDeclareArguments,
|
|
||||||
},
|
|
||||||
connection::{Connection, OpenConnectionArguments},
|
|
||||||
consumer::AsyncConsumer,
|
|
||||||
};
|
};
|
||||||
|
use log::info;
|
||||||
use revolt_config::{Settings, config, configure};
|
use revolt_config::{Settings, config, configure};
|
||||||
use revolt_database::DatabaseInfo;
|
use revolt_database::{Database, DatabaseInfo, amqp::consumer::{Consumer, Delegate}};
|
||||||
use revolt_search::ElasticsearchClient;
|
use revolt_search::ElasticsearchClient;
|
||||||
use tokio::{signal::ctrl_c, spawn};
|
use tokio::{signal::ctrl_c, spawn};
|
||||||
|
use std::{marker::PhantomData, sync::Arc};
|
||||||
|
|
||||||
mod consumers;
|
mod consumers;
|
||||||
mod index;
|
mod index;
|
||||||
@@ -38,53 +36,63 @@ async fn _main() {
|
|||||||
client.setup_indexes().await.unwrap();
|
client.setup_indexes().await.unwrap();
|
||||||
};
|
};
|
||||||
|
|
||||||
let connection = Connection::open(&OpenConnectionArguments::new(
|
let connection = Arc::new(
|
||||||
&config.rabbit.host,
|
Connection::connect(
|
||||||
config.rabbit.port,
|
&format!(
|
||||||
&config.rabbit.username,
|
"amqp://{}:{}@{}:{}",
|
||||||
&config.rabbit.password,
|
&config.rabbit.username,
|
||||||
))
|
&config.rabbit.password,
|
||||||
.await
|
&config.rabbit.host,
|
||||||
.expect("Failed to connect to RabbitMQ");
|
&config.rabbit.port,
|
||||||
|
),
|
||||||
|
ConnectionProperties::default(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.expect("Failed to connect to RabbitMQ"),
|
||||||
|
);
|
||||||
|
|
||||||
let mut channels = Vec::new();
|
let mut channels = Vec::new();
|
||||||
|
|
||||||
channels.push(
|
channels.push(
|
||||||
make_queue_and_consume(
|
make_queue_and_consume::<consumers::MessageConsumer>(
|
||||||
&config,
|
&client,
|
||||||
|
&db,
|
||||||
&connection,
|
&connection,
|
||||||
|
&config,
|
||||||
&config.elasticsearch.message_queue,
|
&config.elasticsearch.message_queue,
|
||||||
consumers::MessageConsumer::new(client.clone(), db.clone()),
|
|
||||||
)
|
)
|
||||||
.await,
|
.await,
|
||||||
);
|
);
|
||||||
|
|
||||||
channels.push(
|
channels.push(
|
||||||
make_queue_and_consume(
|
make_queue_and_consume::<consumers::MessageEditConsumer>(
|
||||||
&config,
|
&client,
|
||||||
|
&db,
|
||||||
&connection,
|
&connection,
|
||||||
|
&config,
|
||||||
&config.elasticsearch.message_edit_queue,
|
&config.elasticsearch.message_edit_queue,
|
||||||
consumers::MessageEditConsumer::new(client.clone(), db.clone()),
|
|
||||||
)
|
)
|
||||||
.await,
|
.await,
|
||||||
);
|
);
|
||||||
|
|
||||||
channels.push(
|
channels.push(
|
||||||
make_queue_and_consume(
|
make_queue_and_consume::<consumers::MessageDeleteConsumer>(
|
||||||
&config,
|
&client,
|
||||||
|
&db,
|
||||||
&connection,
|
&connection,
|
||||||
|
&config,
|
||||||
&config.elasticsearch.message_delete_queue,
|
&config.elasticsearch.message_delete_queue,
|
||||||
consumers::MessageDeleteConsumer::new(client.clone(), db.clone()),
|
|
||||||
)
|
)
|
||||||
.await,
|
.await,
|
||||||
);
|
);
|
||||||
|
|
||||||
channels.push(
|
channels.push(
|
||||||
make_queue_and_consume(
|
make_queue_and_consume::<consumers::ChannelDeleteConsumer>(
|
||||||
&config,
|
&client,
|
||||||
|
&db,
|
||||||
&connection,
|
&connection,
|
||||||
|
&config,
|
||||||
&config.elasticsearch.channel_delete_queue,
|
&config.elasticsearch.channel_delete_queue,
|
||||||
consumers::ChannelDeleteConsumer::new(client.clone(), db.clone()),
|
|
||||||
)
|
)
|
||||||
.await,
|
.await,
|
||||||
);
|
);
|
||||||
@@ -98,10 +106,10 @@ async fn _main() {
|
|||||||
task = Some(spawn(index::index_existing_messages(db, client.clone())));
|
task = Some(spawn(index::index_existing_messages(db, client.clone())));
|
||||||
}
|
}
|
||||||
|
|
||||||
ctrl_c().await.expect("Failed to wait for ctrl-c");
|
ctrl_c().await.unwrap();
|
||||||
|
|
||||||
for channel in channels {
|
for channel in channels {
|
||||||
channel.close().await.unwrap();
|
let _ = channel.close(0, "close".into()).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(task) = task {
|
if let Some(task) = task {
|
||||||
@@ -109,52 +117,85 @@ async fn _main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn make_queue_and_consume<F: AsyncConsumer + Send + 'static>(
|
async fn make_queue_and_consume<F: Consumer<ElasticsearchClient>>(
|
||||||
|
client: &ElasticsearchClient,
|
||||||
|
db: &Database,
|
||||||
|
connection: &Arc<Connection>,
|
||||||
config: &Settings,
|
config: &Settings,
|
||||||
connection: &Connection,
|
queue_name: &str,
|
||||||
queue: &str,
|
) -> Arc<Channel> {
|
||||||
consumer: F,
|
let channel = Arc::new(connection.create_channel().await.unwrap());
|
||||||
) -> Channel {
|
|
||||||
let channel = connection.open_channel(None).await.unwrap();
|
|
||||||
|
|
||||||
channel
|
channel
|
||||||
.exchange_declare(
|
.exchange_declare(
|
||||||
ExchangeDeclareArguments::new(&config.elasticsearch.exchange, "direct")
|
config.elasticsearch.exchange.clone().into(),
|
||||||
.durable(true)
|
lapin::ExchangeKind::Direct,
|
||||||
.finish(),
|
ExchangeDeclareOptions {
|
||||||
|
durable: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
FieldTable::default(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to declare pushd exchange");
|
.expect("Failed to declare exchange");
|
||||||
|
|
||||||
let mut table = FieldTable::new();
|
let mut table = FieldTable::default();
|
||||||
table.insert("x-queue-type".try_into().unwrap(), "quorum".into());
|
table.insert("x-queue-type".try_into().unwrap(), AMQPValue::LongString("quorum".into()));
|
||||||
|
|
||||||
_ = channel
|
let args = QueueDeclareOptions {
|
||||||
.queue_declare(
|
durable: true,
|
||||||
QueueDeclareArguments::new(queue)
|
..Default::default()
|
||||||
.durable(true)
|
};
|
||||||
.arguments(table)
|
|
||||||
.finish(),
|
channel
|
||||||
)
|
.queue_declare(queue_name.into(), args, table)
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
channel
|
channel
|
||||||
.queue_bind(QueueBindArguments::new(
|
.queue_bind(
|
||||||
queue,
|
queue_name.into(),
|
||||||
&config.elasticsearch.exchange,
|
config.elasticsearch.exchange.clone().into(),
|
||||||
queue,
|
queue_name.into(),
|
||||||
))
|
QueueBindOptions::default(),
|
||||||
|
FieldTable::default(),
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.expect("This probably means the revolt.messages exchange does not exist in rabbitmq!");
|
.expect(
|
||||||
|
"This probably means the revolt.messages exchange does not exist in rabbitmq!",
|
||||||
|
);
|
||||||
|
|
||||||
let args = BasicConsumeArguments::new(queue, "")
|
|
||||||
.manual_ack(true)
|
|
||||||
.finish();
|
|
||||||
|
|
||||||
let tag = channel.basic_consume(consumer, args).await.unwrap();
|
let consumer = channel
|
||||||
log::info!("Consuming queue {queue}, tag {tag}");
|
.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
|
channel
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use revolt_database::{util::reference::Reference, Database};
|
use revolt_database::{util::reference::Reference, Database, AMQP};
|
||||||
use revolt_result::{create_error, Result};
|
use revolt_result::{create_error, Result};
|
||||||
use rocket::State;
|
use rocket::State;
|
||||||
use rocket_empty::EmptyResponse;
|
use rocket_empty::EmptyResponse;
|
||||||
@@ -10,6 +10,7 @@ use rocket_empty::EmptyResponse;
|
|||||||
#[delete("/<webhook_id>/<token>/<message_id>")]
|
#[delete("/<webhook_id>/<token>/<message_id>")]
|
||||||
pub async fn webhook_delete_message(
|
pub async fn webhook_delete_message(
|
||||||
db: &State<Database>,
|
db: &State<Database>,
|
||||||
|
amqp: &State<AMQP>,
|
||||||
webhook_id: Reference<'_>,
|
webhook_id: Reference<'_>,
|
||||||
token: String,
|
token: String,
|
||||||
message_id: Reference<'_>,
|
message_id: Reference<'_>,
|
||||||
@@ -23,5 +24,5 @@ pub async fn webhook_delete_message(
|
|||||||
return Err(create_error!(CannotDeleteMessage));
|
return Err(create_error!(CannotDeleteMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
message.delete(db).await.map(|_| EmptyResponse)
|
message.delete(db, Some(amqp)).await.map(|_| EmptyResponse)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use iso8601_timestamp::Timestamp;
|
|||||||
use revolt_config::config;
|
use revolt_config::config;
|
||||||
use revolt_database::{
|
use revolt_database::{
|
||||||
tasks::process_embeds::queue, util::reference::Reference, Database, Message, PartialMessage,
|
tasks::process_embeds::queue, util::reference::Reference, Database, Message, PartialMessage,
|
||||||
|
AMQP,
|
||||||
};
|
};
|
||||||
use revolt_models::v0::{self, DataEditMessage, Embed};
|
use revolt_models::v0::{self, DataEditMessage, Embed};
|
||||||
use revolt_models::validator::Validate;
|
use revolt_models::validator::Validate;
|
||||||
@@ -15,6 +16,7 @@ use rocket::{serde::json::Json, State};
|
|||||||
#[patch("/<webhook_id>/<token>/<message_id>", data = "<data>")]
|
#[patch("/<webhook_id>/<token>/<message_id>", data = "<data>")]
|
||||||
pub async fn webhook_edit_message(
|
pub async fn webhook_edit_message(
|
||||||
db: &State<Database>,
|
db: &State<Database>,
|
||||||
|
amqp: &State<AMQP>,
|
||||||
webhook_id: Reference<'_>,
|
webhook_id: Reference<'_>,
|
||||||
token: String,
|
token: String,
|
||||||
message_id: Reference<'_>,
|
message_id: Reference<'_>,
|
||||||
@@ -73,7 +75,7 @@ pub async fn webhook_edit_message(
|
|||||||
|
|
||||||
partial.embeds = Some(new_embeds);
|
partial.embeds = Some(new_embeds);
|
||||||
|
|
||||||
message.update(db, partial, vec![]).await?;
|
message.update(db, Some(amqp), partial, vec![]).await?;
|
||||||
|
|
||||||
// Queue up a task for processing embeds
|
// Queue up a task for processing embeds
|
||||||
if let Some(content) = edit.content {
|
if let Some(content) = edit.content {
|
||||||
|
|||||||
@@ -70,6 +70,11 @@
|
|||||||
"path": "crates/core/result/Cargo.toml",
|
"path": "crates/core/result/Cargo.toml",
|
||||||
"jsonpath": "$.package.version"
|
"jsonpath": "$.package.version"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "toml",
|
||||||
|
"path": "crates/core/search/Cargo.toml",
|
||||||
|
"jsonpath": "$.package.version"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "toml",
|
"type": "toml",
|
||||||
"path": "crates/daemons/crond/Cargo.toml",
|
"path": "crates/daemons/crond/Cargo.toml",
|
||||||
@@ -85,6 +90,11 @@
|
|||||||
"path": "crates/daemons/voice-ingress/Cargo.toml",
|
"path": "crates/daemons/voice-ingress/Cargo.toml",
|
||||||
"jsonpath": "$.package.version"
|
"jsonpath": "$.package.version"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "toml",
|
||||||
|
"path": "crates/daemons/searchd/Cargo.toml",
|
||||||
|
"jsonpath": "$.package.version"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "toml",
|
"type": "toml",
|
||||||
"path": "crates/services/autumn/Cargo.toml",
|
"path": "crates/services/autumn/Cargo.toml",
|
||||||
@@ -149,6 +159,11 @@
|
|||||||
"type": "toml",
|
"type": "toml",
|
||||||
"path": "Cargo.toml",
|
"path": "Cargo.toml",
|
||||||
"jsonpath": "$.workspace.dependencies['revolt-result'].version"
|
"jsonpath": "$.workspace.dependencies['revolt-result'].version"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "toml",
|
||||||
|
"path": "Cargo.toml",
|
||||||
|
"jsonpath": "$.workspace.dependencies['revolt-search'].version"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user