feat: implement fullstate on-connect event

This commit is contained in:
atagen 2025-06-21 22:30:12 +10:00
parent 05e12ea2f2
commit 73813605d6
4 changed files with 66 additions and 14 deletions

View file

@ -7,7 +7,7 @@ use std::{
use crate::socket::{create_niri_socket, tell};
use anyhow::{Error, Result, anyhow};
use niri_ipc::{Event, Request};
use niri_tag::{TagCmd, TagEvent};
use niri_tag::{TagCmd, TagEvent, TagState};
use nix::unistd::geteuid;
use smol::{
@ -74,10 +74,14 @@ enum EventsReceivable {
}
#[allow(unreachable_code)]
pub async fn event_provider(rx: channel::Receiver<TagEvent>) -> Result<()> {
pub async fn event_provider(
rx: channel::Receiver<TagEvent>,
fullstate_tx: channel::Sender<channel::Sender<HashMap<u8, TagState>>>,
) -> Result<()> {
tracing::debug!("creating event provider");
let listen = create_provider_socket("event provider", "niri-tag-events").await?;
let mut sockets = BTreeMap::new();
tracing::debug!("beginning event provider loop");
loop {
use EventsReceivable::*;
let recvd: EventsReceivable = future::or(
@ -98,8 +102,22 @@ pub async fn event_provider(rx: channel::Receiver<TagEvent>) -> Result<()> {
BadSockets(Vec<String>),
}
let res = match recvd {
Conn(addr, socket) => {
sockets.insert(addr, socket);
Conn(addr, mut socket) => {
tracing::debug!("received a new event provider connection");
sockets.insert(addr, socket.clone());
let (t, r) = smol::channel::bounded(1);
tracing::debug!("sending fullstate request");
fullstate_tx.send(t).await?;
match r.recv().await {
Ok(fullstate) => {
tracing::debug!("received fullstate, sending");
let data = serde_json::to_string(&TagEvent::TagFullState(fullstate))?;
if let Err(e) = socket.write_all(&[data.as_bytes(), b"\n"].concat()).await {
tracing::error!("Failed to send fullstate to socket: {}", e);
}
}
Err(e) => tracing::error!("Failed to receive fullstate: {}", e),
}
Res::Ok
}
Event(e) => {
@ -113,7 +131,7 @@ pub async fn event_provider(rx: channel::Receiver<TagEvent>) -> Result<()> {
.into_iter()
.fold(Vec::new(), |mut acc, (addr, res)| {
if let Err(e) = res {
tracing::warn!("error on event provider socket {}: {}", addr, e);
tracing::warn!("error from event provider client {}: {}", addr, e);
acc.push(addr.to_owned());
}
acc
@ -131,7 +149,6 @@ pub async fn event_provider(rx: channel::Receiver<TagEvent>) -> Result<()> {
});
}
}
tracing::debug!("beginning ipc provider loop");
Ok(())
}