Update backend implementation to fit spec
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
use anyhow::Result;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use crate::repo::Repo;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Infra {
|
||||
api_url: String,
|
||||
relay_domain: String,
|
||||
livekit_url: String,
|
||||
livekit_api_key: String,
|
||||
livekit_api_secret: String,
|
||||
repo: Repo,
|
||||
last_activity_at: std::sync::Arc<Mutex<i64>>,
|
||||
}
|
||||
|
||||
impl Infra {
|
||||
pub fn new(repo: Repo) -> Self {
|
||||
let api_url = std::env::var("ZOOID_API_URL").unwrap_or_default();
|
||||
let relay_domain = std::env::var("RELAY_DOMAIN").unwrap_or_default();
|
||||
let livekit_url = std::env::var("LIVEKIT_URL").unwrap_or_default();
|
||||
let livekit_api_key = std::env::var("LIVEKIT_API_KEY").unwrap_or_default();
|
||||
let livekit_api_secret = std::env::var("LIVEKIT_API_SECRET").unwrap_or_default();
|
||||
Self {
|
||||
api_url,
|
||||
relay_domain,
|
||||
livekit_url,
|
||||
livekit_api_key,
|
||||
livekit_api_secret,
|
||||
repo,
|
||||
last_activity_at: std::sync::Arc::new(Mutex::new(0)),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn start(self) {
|
||||
let mut interval = tokio::time::interval(std::time::Duration::from_secs(10));
|
||||
loop {
|
||||
interval.tick().await;
|
||||
if let Err(e) = self.tick().await {
|
||||
tracing::error!(error = %e, "infra tick failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn tick(&self) -> Result<()> {
|
||||
let mut since_guard = self.last_activity_at.lock().await;
|
||||
let since = *since_guard;
|
||||
let activity = self.repo.list_activity(&since, None).await?;
|
||||
|
||||
for a in activity {
|
||||
if matches!(
|
||||
a.activity_type.as_str(),
|
||||
"relay_created" | "relay_updated" | "relay_deactivated"
|
||||
) {
|
||||
let Some(relay) = self.repo.get_relay(&a.identifier).await? else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if let Err(e) = self.sync_relay(&relay).await {
|
||||
tracing::warn!(relay = %relay.id, error = %e, "relay sync failed");
|
||||
self.repo.fail_relay_sync(&relay, e.to_string()).await?;
|
||||
}
|
||||
}
|
||||
|
||||
*since_guard = (*since_guard).max(a.created_at);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn sync_relay(&self, relay: &crate::models::Relay) -> Result<()> {
|
||||
let client = reqwest::Client::new();
|
||||
let url = format!("{}/relay/{}", self.api_url.trim_end_matches('/'), relay.id);
|
||||
|
||||
let host = if self.relay_domain.is_empty() {
|
||||
relay.subdomain.clone()
|
||||
} else {
|
||||
format!("{}.{}", relay.subdomain, self.relay_domain)
|
||||
};
|
||||
|
||||
let secret = uuid::Uuid::new_v4().to_string();
|
||||
|
||||
let livekit = if relay.livekit_enabled == 1 {
|
||||
serde_json::json!({
|
||||
"enabled": true,
|
||||
"url": self.livekit_url,
|
||||
"api_key": self.livekit_api_key,
|
||||
"api_secret": self.livekit_api_secret,
|
||||
})
|
||||
} else {
|
||||
serde_json::json!({ "enabled": false })
|
||||
};
|
||||
|
||||
let body = serde_json::json!({
|
||||
"host": host,
|
||||
"schema": relay.schema,
|
||||
"secret": secret,
|
||||
"inactive": relay.status == "inactive",
|
||||
"info": {
|
||||
"name": relay.info_name,
|
||||
"icon": relay.info_icon,
|
||||
"description": relay.info_description,
|
||||
},
|
||||
"policy": {
|
||||
"public_join": relay.policy_public_join == 1,
|
||||
"strip_signatures": relay.policy_strip_signatures == 1,
|
||||
},
|
||||
"groups": { "enabled": relay.groups_enabled == 1 },
|
||||
"management": { "enabled": relay.management_enabled == 1 },
|
||||
"blossom": { "enabled": relay.blossom_enabled == 1 },
|
||||
"livekit": livekit,
|
||||
"push": { "enabled": relay.push_enabled == 1 },
|
||||
"roles": [
|
||||
{ "name": "admin", "permissions": ["read", "write", "admin"] },
|
||||
{ "name": "member", "permissions": ["read", "write"] },
|
||||
{ "name": "guest", "permissions": ["read"] },
|
||||
],
|
||||
});
|
||||
|
||||
let response = client.put(url).json(&body).send().await?;
|
||||
if !response.status().is_success() {
|
||||
anyhow::bail!("zooid sync returned {}", response.status())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user