use crate::entity::time_entry; use crate::sync_service::{update_database, UpdateStats}; use crate::toggl_api::TogglApiClient; use crate::utils; use chrono::{DateTime, FixedOffset}; use migration::Order; use sea_orm::{DatabaseConnection, EntityTrait, QueryOrder, QuerySelect}; use std::ops::Sub; use tracing::{debug, instrument}; #[tracing::instrument(skip(client, db))] pub async fn poll_job(client: TogglApiClient, db: DatabaseConnection, poll_period: u64) { // Periodically poll the Toggl API for new time entries for today to cache them in the database let period = tokio::time::Duration::from_secs(poll_period); loop { tracing::info!("Polling Toggl API"); match perform_poll(&client, &db).await { Ok(poll_update_data) => { tracing::info!("Successfully polled Toggl API: {:?}", poll_update_data); } Err(error) => { tracing::error!("Failed to poll Toggl API: {:?}", error); } } tokio::time::sleep(period).await; } } #[instrument(skip(toggl_client, db))] pub async fn perform_poll( toggl_client: &TogglApiClient, db: &DatabaseConnection, ) -> utils::Result { let since = time_entry::Entity::find() .select_only() .column(time_entry::Column::ServerUpdatedAt) .order_by(time_entry::Column::ServerUpdatedAt, Order::Desc) .into_tuple::>() .one(db) .await?; debug!("Performing poll, last_update_at: {:?}", since); let since = since.unwrap_or( chrono::Utc::now() .sub(chrono::Duration::days(1)) .fixed_offset(), ); let time_entries = toggl_client .fetch_time_entries_modified_since(since.to_utc()) .await?; // These are changes only so there is no need to enforce exclusivity update_database(db, toggl_client, &time_entries, None).await }