Track start time in clients

This commit is contained in:
Joscha 2024-12-28 18:59:02 +01:00
parent 51ee7b9246
commit e462e9419a
5 changed files with 50 additions and 10 deletions

View file

@ -1,7 +1,6 @@
use std::{fmt::Debug, sync::Arc}; use std::{fmt::Debug, sync::Arc};
use euphoxide_client::{MultiClient, MultiClientConfig, MultiClientEvent, ServerConfig}; use euphoxide_client::{MultiClient, MultiClientConfig, MultiClientEvent, ServerConfig};
use jiff::Timestamp;
use log::error; use log::error;
use tokio::sync::mpsc; use tokio::sync::mpsc;
@ -12,7 +11,6 @@ pub struct Bot<E = euphoxide::Error> {
pub server_config: ServerConfig, pub server_config: ServerConfig,
pub commands: Arc<Commands<E>>, pub commands: Arc<Commands<E>>,
pub clients: MultiClient, pub clients: MultiClient,
pub start_time: Timestamp,
} }
impl Bot { impl Bot {
@ -37,10 +35,10 @@ impl<E> Bot<E> {
server_config, server_config,
commands: Arc::new(commands), commands: Arc::new(commands),
clients: MultiClient::new_with_config(clients_config, event_tx), clients: MultiClient::new_with_config(clients_config, event_tx),
start_time: Timestamp::now(),
} }
} }
} }
impl<E> Bot<E> impl<E> Bot<E>
where where
E: Debug + 'static, E: Debug + 'static,
@ -61,7 +59,6 @@ impl<E> Clone for Bot<E> {
server_config: self.server_config.clone(), server_config: self.server_config.clone(),
commands: self.commands.clone(), commands: self.commands.clone(),
clients: self.clients.clone(), clients: self.clients.clone(),
start_time: self.start_time,
} }
} }
} }

View file

@ -62,8 +62,14 @@ pub trait HasStartTime {
} }
impl Uptime { impl Uptime {
fn formulate_reply<E>(&self, ctx: &Context, bot: &Bot<E>, connected: bool) -> String { fn formulate_reply<E>(
let start = bot.start_time; &self,
ctx: &Context,
bot: &Bot<E>,
joined: bool,
connected: bool,
) -> String {
let start = bot.clients.start_time();
let now = Timestamp::now(); let now = Timestamp::now();
let mut reply = format!( let mut reply = format!(
@ -72,6 +78,15 @@ impl Uptime {
format_relative_time(start - now), format_relative_time(start - now),
); );
if joined {
let since = ctx.client.start_time();
reply.push_str(&format!(
", present since {} ({})",
format_time(since),
format_relative_time(since - now),
));
}
if connected { if connected {
let since = ctx.joined.since; let since = ctx.joined.since;
reply.push_str(&format!( reply.push_str(&format!(
@ -98,7 +113,7 @@ where
bot: &Bot<E>, bot: &Bot<E>,
) -> Result<Propagate, E> { ) -> Result<Propagate, E> {
if arg.trim().is_empty() { if arg.trim().is_empty() {
let reply = self.formulate_reply(ctx, bot, false); let reply = self.formulate_reply(ctx, bot, false, false);
ctx.reply_only(msg.id, reply).await?; ctx.reply_only(msg.id, reply).await?;
Ok(Propagate::No) Ok(Propagate::No)
} else { } else {
@ -111,6 +126,9 @@ where
#[cfg(feature = "clap")] #[cfg(feature = "clap")]
#[derive(Parser)] #[derive(Parser)]
pub struct UptimeArgs { pub struct UptimeArgs {
/// Show how long the bot has been in this room.
#[arg(long, short)]
pub present: bool,
/// Show how long the bot has been connected without interruption. /// Show how long the bot has been connected without interruption.
#[arg(long, short)] #[arg(long, short)]
pub connected: bool, pub connected: bool,
@ -131,7 +149,7 @@ where
ctx: &Context, ctx: &Context,
bot: &Bot<E>, bot: &Bot<E>,
) -> Result<Propagate, E> { ) -> Result<Propagate, E> {
let reply = self.formulate_reply(ctx, bot, args.connected); let reply = self.formulate_reply(ctx, bot, args.present, args.connected);
ctx.reply_only(msg.id, reply).await?; ctx.reply_only(msg.id, reply).await?;
Ok(Propagate::No) Ok(Propagate::No)
} }

View file

@ -6,6 +6,7 @@ edition = { workspace = true }
[dependencies] [dependencies]
cookie = { workspace = true } cookie = { workspace = true }
euphoxide = { workspace = true } euphoxide = { workspace = true }
jiff = { workspace = true }
log = { workspace = true } log = { workspace = true }
tokio = { workspace = true, features = ["rt"] } tokio = { workspace = true, features = ["rt"] }
tokio-tungstenite = { workspace = true } tokio-tungstenite = { workspace = true }

View file

@ -4,6 +4,7 @@ use euphoxide::{
api::ParsedPacket, api::ParsedPacket,
client::{conn::ClientConnHandle, state::State}, client::{conn::ClientConnHandle, state::State},
}; };
use jiff::Timestamp;
use tokio::{ use tokio::{
select, select,
sync::{mpsc, oneshot}, sync::{mpsc, oneshot},
@ -160,6 +161,7 @@ impl MultiClientTask {
pub struct MultiClient { pub struct MultiClient {
config: Arc<MultiClientConfig>, config: Arc<MultiClientConfig>,
cmd_tx: mpsc::Sender<Command>, cmd_tx: mpsc::Sender<Command>,
start_time: Timestamp,
} }
impl MultiClient { impl MultiClient {
@ -171,6 +173,8 @@ impl MultiClient {
config: MultiClientConfig, config: MultiClientConfig,
event_tx: mpsc::Sender<MultiClientEvent>, event_tx: mpsc::Sender<MultiClientEvent>,
) -> Self { ) -> Self {
let start_time = Timestamp::now();
let config = Arc::new(config); let config = Arc::new(config);
let out_tx = event_tx; let out_tx = event_tx;
@ -188,7 +192,15 @@ impl MultiClient {
tokio::task::spawn(task.run()); tokio::task::spawn(task.run());
Self { config, cmd_tx } Self {
config,
cmd_tx,
start_time,
}
}
pub fn start_time(&self) -> Timestamp {
self.start_time
} }
pub async fn get_clients(&self) -> Vec<Client> { pub async fn get_clients(&self) -> Vec<Client> {

View file

@ -8,6 +8,7 @@ use euphoxide::{
state::State, state::State,
}, },
}; };
use jiff::Timestamp;
use log::warn; use log::warn;
use tokio::{ use tokio::{
select, select,
@ -337,6 +338,7 @@ impl ClientTask {
pub struct Client { pub struct Client {
id: usize, id: usize,
cmd_tx: mpsc::Sender<Command>, cmd_tx: mpsc::Sender<Command>,
start_time: Timestamp,
} }
impl fmt::Debug for Client { impl fmt::Debug for Client {
@ -349,6 +351,8 @@ impl fmt::Debug for Client {
impl Client { impl Client {
pub fn new(id: usize, config: ClientConfig, event_tx: mpsc::Sender<ClientEvent>) -> Self { pub fn new(id: usize, config: ClientConfig, event_tx: mpsc::Sender<ClientEvent>) -> Self {
let start_time = Timestamp::now();
let (cmd_tx, cmd_rx) = mpsc::channel(config.server.cmd_channel_bufsize); let (cmd_tx, cmd_rx) = mpsc::channel(config.server.cmd_channel_bufsize);
let task = ClientTask { let task = ClientTask {
@ -362,13 +366,21 @@ impl Client {
tokio::task::spawn(task.run()); tokio::task::spawn(task.run());
Self { id, cmd_tx } Self {
id,
cmd_tx,
start_time,
}
} }
pub fn id(&self) -> usize { pub fn id(&self) -> usize {
self.id self.id
} }
pub fn start_time(&self) -> Timestamp {
self.start_time
}
pub fn stopped(&self) -> bool { pub fn stopped(&self) -> bool {
self.cmd_tx.is_closed() self.cmd_tx.is_closed()
} }