11use std:: { fmt:: Display , future:: Future , pin:: Pin , time:: Duration } ;
22
3+ use humantime_serde:: re:: humantime;
34use spdlog:: prelude:: * ;
45use tokio:: { sync:: mpsc, time:: MissedTickBehavior } ;
56
@@ -13,6 +14,7 @@ use crate::{
1314pub struct TaskSubscription {
1415 name : String ,
1516 interval : Duration ,
17+ initial_offset : Option < Duration > ,
1618 notifiers : Vec < Box < dyn NotifierTrait > > ,
1719 sourcer : Option < Sourcer > , // took when the task is running
1820}
@@ -21,52 +23,74 @@ impl TaskSubscription {
2123 pub fn new (
2224 name : String ,
2325 interval : Duration ,
26+ initial_offset : Option < Duration > ,
2427 notify : Vec < Accessor < NotifierConfig > > ,
2528 source_platform : & Accessor < SourceConfig > ,
2629 ) -> Self {
30+ trace ! (
31+ "task subscription '{name}' created, source '{source_platform}', interval {} (initial offset {})" ,
32+ humantime:: format_duration( interval) ,
33+ humantime:: format_duration( initial_offset. unwrap_or_default( ) )
34+ ) ;
2735 Self {
2836 name,
2937 interval,
38+ initial_offset,
3039 notifiers : notify. into_iter ( ) . map ( notifier) . collect ( ) ,
3140 sourcer : Some ( sourcer ( source_platform) ) ,
3241 }
3342 }
3443
3544 // Handler for poll-based subscription
3645 async fn continuous_fetch ( & mut self , fetcher : Box < dyn FetcherTrait > ) {
37- let mut interval = tokio:: time:: interval ( self . interval ) ;
38- interval. set_missed_tick_behavior ( MissedTickBehavior :: Delay ) ;
39- interval. reset_immediately ( ) ;
40-
4146 let mut last_status = Status :: empty ( ) ;
4247
43- loop {
44- interval. tick ( ) . await ;
45-
46- let Ok ( mut status) = fetcher. fetch_status ( ) . await . inspect_err ( |err| {
47- error ! (
48- "failed to fetch status for '{}' on '{}': {err}" ,
49- self . name, fetcher
50- )
51- } ) else {
52- continue ;
53- } ;
54-
55- status. sort ( ) ;
48+ // Fetch for the first time immediately
49+ self . continuous_fetch_once ( & * fetcher, & mut last_status)
50+ . await ;
5651
57- trace ! (
58- "status of '{}' on '{fetcher}' now is '{status:?}'" ,
59- self . name
60- ) ;
52+ if let Some ( initial_offset) = self . initial_offset {
53+ tokio:: time:: sleep ( initial_offset) . await ;
54+ }
6155
62- let notifications = status . generate_notifications ( & last_status ) ;
63- self . notify ( notifications , & fetcher ) . await ;
56+ let mut interval = tokio :: time :: interval ( self . interval ) ;
57+ interval . set_missed_tick_behavior ( MissedTickBehavior :: Delay ) ;
6458
65- last_status. update_incrementally ( status) ;
66- trace ! ( "subscription '{}' updated once" , self . name) ;
59+ loop {
60+ interval. tick ( ) . await ;
61+ self . continuous_fetch_once ( & * fetcher, & mut last_status)
62+ . await ;
6763 }
6864 }
6965
66+ async fn continuous_fetch_once (
67+ & mut self ,
68+ fetcher : & dyn FetcherTrait ,
69+ last_status : & mut Status ,
70+ ) {
71+ let Ok ( mut status) = fetcher. fetch_status ( ) . await . inspect_err ( |err| {
72+ error ! (
73+ "failed to fetch status for '{}' on '{}': {err}" ,
74+ self . name, fetcher
75+ )
76+ } ) else {
77+ return ;
78+ } ;
79+
80+ status. sort ( ) ;
81+
82+ trace ! (
83+ "status of '{}' on '{fetcher}' now is '{status:?}'" ,
84+ self . name
85+ ) ;
86+
87+ let notifications = status. generate_notifications ( last_status) ;
88+ self . notify ( notifications, & fetcher) . await ;
89+
90+ last_status. update_incrementally ( status) ;
91+ trace ! ( "subscription '{}' updated once" , self . name) ;
92+ }
93+
7094 // Handler for listen-based subscription
7195 async fn continuous_wait (
7296 & mut self ,
0 commit comments