Fix disappearing idle time after timeout

The active time was reported within idle time for idle_timeout. This caused disappearing the idle event.
The temporary solution sometimes sacrificies idle_timeout of active time.
This commit is contained in:
Demmie 2024-06-24 00:55:13 -04:00
parent 3e478e9054
commit 123a0e45ff
No known key found for this signature in database
GPG Key ID: B06DAA3D432C6E9A
2 changed files with 39 additions and 5 deletions

View File

@ -30,7 +30,6 @@ jobs:
components: clippy components: clippy
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
- run: cargo clippy --locked --all-targets --all-features --workspace -- -D warnings - run: cargo clippy --locked --all-targets --all-features --workspace -- -D warnings
- run: cargo clippy --locked --all-targets --workspace -- -D warnings
clippy: clippy:
runs-on: ubuntu-latest runs-on: ubuntu-latest
env: env:

View File

@ -8,6 +8,9 @@ pub struct State {
is_idle: bool, is_idle: bool,
is_changed: bool, is_changed: bool,
idle_timeout: Duration, idle_timeout: Duration,
idle_start: Option<DateTime<Utc>>,
idle_end: Option<DateTime<Utc>>,
} }
impl State { impl State {
@ -18,6 +21,8 @@ impl State {
is_idle: false, is_idle: false,
is_changed: false, is_changed: false,
idle_timeout, idle_timeout,
idle_start: None,
idle_end: None,
} }
} }
@ -30,10 +35,14 @@ impl State {
pub fn mark_not_idle(&mut self) { pub fn mark_not_idle(&mut self) {
self.last_input_time = Utc::now(); self.last_input_time = Utc::now();
self.set_idle(false, self.last_input_time); self.set_idle(false, self.last_input_time);
self.idle_end = self.changed_time.into();
} }
pub fn mark_idle(&mut self) { pub fn mark_idle(&mut self) {
self.set_idle(true, Utc::now()); self.set_idle(true, Utc::now());
self.idle_start = self.changed_time.into();
} }
// The logic is rewritten from the original Python code: // The logic is rewritten from the original Python code:
@ -67,6 +76,18 @@ impl State {
let now = Utc::now(); let now = Utc::now();
if !self.is_idle { if !self.is_idle {
self.last_input_time = max(now - self.idle_timeout, self.changed_time); self.last_input_time = max(now - self.idle_timeout, self.changed_time);
if let (Some(idle_start), Some(idle_end)) = (self.idle_start, self.idle_end) {
if !self.is_changed
&& idle_start <= self.last_input_time
&& self.last_input_time <= idle_end
{
warn!("Active time may not be accounted for.");
// TODO: send the correct timings.
// After idle_end there is some active time for idle_timeout which may be accounted as idle time if it becomes idle soon.
return Ok(());
}
}
} }
self.send_ping(now, client).await self.send_ping(now, client).await
@ -79,7 +100,11 @@ impl State {
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
if self.is_changed { if self.is_changed {
let result = if self.is_idle { let result = if self.is_idle {
debug!("Reporting as changed to idle"); debug!(
"Reporting as changed to idle for {} seconds since {}",
(now - self.last_input_time).num_seconds(),
self.last_input_time.format("%Y-%m-%d %H:%M:%S"),
);
client client
.ping(false, self.last_input_time, Duration::zero()) .ping(false, self.last_input_time, Duration::zero())
.await?; .await?;
@ -90,7 +115,10 @@ impl State {
.ping(true, self.last_input_time, now - self.last_input_time) .ping(true, self.last_input_time, now - self.last_input_time)
.await .await
} else { } else {
debug!("Reporting as no longer idle"); debug!(
"Reporting as no longer idle at {}",
self.last_input_time.format("%Y-%m-%d %H:%M:%S")
);
client client
.ping(true, self.last_input_time, Duration::zero()) .ping(true, self.last_input_time, Duration::zero())
@ -107,12 +135,19 @@ impl State {
self.is_changed = false; self.is_changed = false;
result result
} else if self.is_idle { } else if self.is_idle {
trace!("Reporting as idle"); trace!(
"Reporting as idle for {} seconds since {}",
(now - self.last_input_time).num_seconds(),
self.last_input_time.format("%Y-%m-%d %H:%M:%S"),
);
client client
.ping(true, self.last_input_time, now - self.last_input_time) .ping(true, self.last_input_time, now - self.last_input_time)
.await .await
} else { } else {
trace!("Reporting as not idle"); trace!(
"Reporting as not idle at {}",
self.last_input_time.format("%Y-%m-%d %H:%M:%S")
);
client client
.ping(false, self.last_input_time, Duration::zero()) .ping(false, self.last_input_time, Duration::zero())
.await .await