split xmpp projection into a separate crate

This commit is contained in:
Nikita Vilunov 2023-10-01 01:47:18 +02:00
parent 854a244dbc
commit dc0a101fe6
8 changed files with 63 additions and 51 deletions

25
Cargo.lock generated
View File

@ -858,19 +858,15 @@ dependencies = [
"mgmt-api", "mgmt-api",
"nonempty", "nonempty",
"projection-irc", "projection-irc",
"projection-xmpp",
"prometheus", "prometheus",
"proto-xmpp",
"quick-xml",
"regex", "regex",
"reqwest", "reqwest",
"rustls-pemfile",
"serde", "serde",
"serde_json", "serde_json",
"tokio", "tokio",
"tokio-rustls",
"tracing", "tracing",
"tracing-subscriber", "tracing-subscriber",
"uuid",
] ]
[[package]] [[package]]
@ -1267,6 +1263,25 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "projection-xmpp"
version = "0.0.1-dev"
dependencies = [
"anyhow",
"derive_more",
"futures-util",
"lavina-core",
"prometheus",
"proto-xmpp",
"quick-xml",
"rustls-pemfile",
"serde",
"tokio",
"tokio-rustls",
"tracing",
"uuid",
]
[[package]] [[package]]
name = "prometheus" name = "prometheus"
version = "0.13.3" version = "0.13.3"

View File

@ -47,14 +47,10 @@ tracing-subscriber = "0.3.16"
futures-util.workspace = true futures-util.workspace = true
prometheus.workspace = true prometheus.workspace = true
nonempty.workspace = true nonempty.workspace = true
tokio-rustls = "0.24.1"
rustls-pemfile = "1.0.2"
quick-xml.workspace = true
derive_more.workspace = true derive_more.workspace = true
uuid = { version = "1.3.0", features = ["v4"] }
lavina-core.workspace = true lavina-core.workspace = true
projection-irc = { path = "crates/projection-irc" } projection-irc = { path = "crates/projection-irc" }
proto-xmpp = { path = "crates/proto-xmpp" } projection-xmpp = { path = "crates/projection-xmpp" }
mgmt-api = { path = "crates/mgmt-api" } mgmt-api = { path = "crates/mgmt-api" }
clap.workspace = true clap.workspace = true

View File

@ -7,9 +7,10 @@ version.workspace = true
lavina-core.workspace = true lavina-core.workspace = true
tracing.workspace = true tracing.workspace = true
anyhow.workspace = true anyhow.workspace = true
nonempty.workspace = true
serde.workspace = true serde.workspace = true
tokio.workspace = true tokio.workspace = true
prometheus.workspace = true prometheus.workspace = true
proto-irc = { path = "../proto-irc" }
futures-util.workspace = true futures-util.workspace = true
nonempty.workspace = true
proto-irc = { path = "../proto-irc" }

View File

@ -0,0 +1,20 @@
[package]
name = "projection-xmpp"
edition = "2021"
version.workspace = true
[dependencies]
lavina-core.workspace = true
tracing.workspace = true
anyhow.workspace = true
serde.workspace = true
tokio.workspace = true
prometheus.workspace = true
futures-util.workspace = true
quick-xml.workspace = true
proto-xmpp = { path = "../proto-xmpp" }
uuid = { version = "1.3.0", features = ["v4"] }
tokio-rustls = "0.24.1"
rustls-pemfile = "1.0.2"
derive_more.workspace = true

View File

@ -1,3 +1,5 @@
#![feature(generators, generator_trait, type_alias_impl_trait, impl_trait_in_assoc_type)]
mod proto; mod proto;
use std::collections::HashMap; use std::collections::HashMap;
@ -7,6 +9,7 @@ use std::net::SocketAddr;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
use anyhow::anyhow;
use futures_util::future::join_all; use futures_util::future::join_all;
use prometheus::Registry as MetricsRegistry; use prometheus::Registry as MetricsRegistry;
use quick_xml::events::{BytesDecl, Event}; use quick_xml::events::{BytesDecl, Event};
@ -117,21 +120,15 @@ pub async fn launch(
} }
} }
log::info!("Stopping XMPP projection"); log::info!("Stopping XMPP projection");
join_all( join_all(actors.into_iter().map(|(socket_addr, terminator)| async move {
actors log::debug!("Stopping XMPP connection at {socket_addr}");
.into_iter() match terminator.terminate().await {
.map(|(socket_addr, terminator)| async move { Ok(_) => log::debug!("Stopped XMPP connection at {socket_addr}"),
log::debug!("Stopping XMPP connection at {socket_addr}"); Err(err) => {
match terminator.terminate().await { log::warn!("XMPP connection to {socket_addr} finished with error: {err}")
Ok(_) => log::debug!("Stopped XMPP connection at {socket_addr}"), }
Err(err) => { }
log::warn!( }))
"XMPP connection to {socket_addr} finished with error: {err}"
)
}
}
}),
)
.await; .await;
log::info!("Stopped XMPP projection"); log::info!("Stopped XMPP projection");
Ok(()) Ok(())
@ -172,9 +169,7 @@ async fn handle_socket(
let authenticated = socket_auth(&mut xml_reader, &mut xml_writer, &mut reader_buf).await?; let authenticated = socket_auth(&mut xml_reader, &mut xml_writer, &mut reader_buf).await?;
log::debug!("User authenticated"); log::debug!("User authenticated");
let mut connection = players let mut connection = players.connect_to_player(authenticated.player_id.clone()).await;
.connect_to_player(authenticated.player_id.clone())
.await;
socket_final( socket_final(
&mut xml_reader, &mut xml_reader,
&mut xml_writer, &mut xml_writer,
@ -396,10 +391,7 @@ async fn handle_packet(
{ {
if server.0.as_ref() == "rooms.localhost" && m.r#type == MessageType::Groupchat { if server.0.as_ref() == "rooms.localhost" && m.r#type == MessageType::Groupchat {
user_handle user_handle
.send_message( .send_message(RoomId::from(name.0.clone())?, m.body.clone().into())
RoomId::from(name.0.clone())?,
m.body.clone().into(),
)
.await?; .await?;
Message { Message {
to: Some(Jid { to: Some(Jid {
@ -448,9 +440,7 @@ async fn handle_packet(
resource: Some(resource), resource: Some(resource),
}) = p.to }) = p.to
{ {
let a = user_handle let a = user_handle.join_room(RoomId::from(name.0.clone())?).await?;
.join_room(RoomId::from(name.0.clone())?)
.await?;
Presence::<()> { Presence::<()> {
to: Some(Jid { to: Some(Jid {
name: Some(user.xmpp_name.clone()), name: Some(user.xmpp_name.clone()),
@ -633,13 +623,13 @@ async fn read_xml_header(
if &*encoding == b"UTF-8" { if &*encoding == b"UTF-8" {
Ok(()) Ok(())
} else { } else {
Err(fail(format!("Unsupported encoding: {encoding:?}").as_str())) Err(anyhow!("Unsupported encoding: {encoding:?}"))
} }
} else { } else {
// Err(fail("No XML encoding provided")) // Err(fail("No XML encoding provided"))
Ok(()) Ok(())
} }
} else { } else {
Err(fail("Expected XML header")) Err(anyhow!("Expected XML header"))
} }
} }

View File

@ -1,11 +1,3 @@
#![feature(
generators,
generator_trait,
type_alias_impl_trait,
impl_trait_in_assoc_type
)]
mod projections;
mod util; mod util;
use std::future::Future; use std::future::Future;
@ -26,7 +18,7 @@ use lavina_core::room::RoomRegistry;
struct ServerConfig { struct ServerConfig {
telemetry: util::telemetry::ServerConfig, telemetry: util::telemetry::ServerConfig,
irc: projection_irc::ServerConfig, irc: projection_irc::ServerConfig,
xmpp: projections::xmpp::ServerConfig, xmpp: projection_xmpp::ServerConfig,
storage: lavina_core::repo::StorageConfig, storage: lavina_core::repo::StorageConfig,
} }
@ -64,7 +56,7 @@ async fn main() -> Result<()> {
let telemetry_terminator = let telemetry_terminator =
util::telemetry::launch(telemetry_config, metrics.clone(), rooms.clone(), storage.clone()).await?; util::telemetry::launch(telemetry_config, metrics.clone(), rooms.clone(), storage.clone()).await?;
let irc = projection_irc::launch(irc_config, players.clone(), rooms.clone(), metrics.clone(), storage.clone()).await?; let irc = projection_irc::launch(irc_config, players.clone(), rooms.clone(), metrics.clone(), storage.clone()).await?;
let xmpp = projections::xmpp::launch(xmpp_config, players.clone(), rooms.clone(), metrics.clone()).await?; let xmpp = projection_xmpp::launch(xmpp_config, players.clone(), rooms.clone(), metrics.clone()).await?;
tracing::info!("Started"); tracing::info!("Started");
sleep.await; sleep.await;

View File

@ -1,2 +0,0 @@
//! Protocol projections — implementations of public APIs.
pub mod xmpp;