11mod worker;
22
3+ use std:: sync:: Arc ;
34use std:: time:: Duration ;
45
56use code0_flow:: flow_config:: load_env_file;
@@ -27,7 +28,7 @@ pub async fn run() {
2728 let client = connect_nats ( & config) . await ;
2829
2930 let mut health_task = spawn_health_task ( & config) ;
30- let ( runtime_status_service, runtime_usage_service) =
31+ let ( runtime_status_service, runtime_usage_service, mut runtime_status_heartbeat_task ) =
3132 setup_dynamic_services_if_needed ( & config) . await ;
3233
3334 let nats_remote = NATSRemoteRuntime :: new ( client. clone ( ) ) ;
@@ -41,6 +42,14 @@ pub async fn run() {
4142 ) ;
4243
4344 wait_for_shutdown ( & mut worker_task, & mut health_task) . await ;
45+ if let Some ( handle) = runtime_status_heartbeat_task. take ( ) {
46+ handle. abort ( ) ;
47+ if let Err ( err) = handle. await {
48+ if !err. is_cancelled ( ) {
49+ log:: warn!( "Runtime status heartbeat task ended unexpectedly: {}" , err) ;
50+ }
51+ }
52+ }
4453 update_stopped_status ( runtime_status_service. as_ref ( ) ) . await ;
4554
4655 log:: info!( "Taurus shutdown complete" ) ;
@@ -95,11 +104,12 @@ fn spawn_health_task(config: &Config) -> Option<JoinHandle<()>> {
95104async fn setup_dynamic_services_if_needed (
96105 config : & Config ,
97106) -> (
98- Option < TaurusRuntimeStatusService > ,
107+ Option < Arc < TaurusRuntimeStatusService > > ,
99108 Option < TaurusRuntimeUsageService > ,
109+ Option < JoinHandle < ( ) > > ,
100110) {
101111 if config. mode != DYNAMIC {
102- return ( None , None ) ;
112+ return ( None , None , None ) ;
103113 }
104114
105115 push_definitions_until_success ( config) . await ;
@@ -109,23 +119,59 @@ async fn setup_dynamic_services_if_needed(
109119 . await ,
110120 ) ;
111121
112- let runtime_status_service = Some (
122+ let runtime_status_service = Some ( Arc :: new (
113123 TaurusRuntimeStatusService :: from_url (
114124 config. aquila_url . clone ( ) ,
115125 config. aquila_token . clone ( ) ,
116126 "taurus" . into ( ) ,
117127 runtime_features ( ) ,
118128 )
119129 . await ,
120- ) ;
130+ ) ) ;
121131
122132 if let Some ( status_service) = runtime_status_service. as_ref ( ) {
123133 status_service
124134 . update_runtime_status ( tucana:: shared:: execution_runtime_status:: Status :: Running )
125135 . await ;
126136 }
127137
128- ( runtime_status_service, runtime_usage_service)
138+ let runtime_status_heartbeat_task = if config. adapter_status_update_interval_seconds > 0 {
139+ let status_service = runtime_status_service
140+ . as_ref ( )
141+ . expect ( "runtime status service should exist in dynamic mode" )
142+ . clone ( ) ;
143+ let update_interval_seconds = config. adapter_status_update_interval_seconds ;
144+
145+ let handle = tokio:: spawn ( async move {
146+ let mut interval = tokio:: time:: interval ( Duration :: from_secs ( update_interval_seconds) ) ;
147+ interval. set_missed_tick_behavior ( tokio:: time:: MissedTickBehavior :: Skip ) ;
148+
149+ // First tick is immediate; consume it so heartbeats start after the interval.
150+ interval. tick ( ) . await ;
151+
152+ loop {
153+ interval. tick ( ) . await ;
154+ status_service
155+ . update_runtime_status ( tucana:: shared:: execution_runtime_status:: Status :: Running )
156+ . await ;
157+ }
158+ } ) ;
159+
160+ log:: info!(
161+ "Runtime status heartbeat started (interval={}s)" ,
162+ update_interval_seconds
163+ ) ;
164+ Some ( handle)
165+ } else {
166+ log:: info!( "Runtime status heartbeat is disabled" ) ;
167+ None
168+ } ;
169+
170+ (
171+ runtime_status_service,
172+ runtime_usage_service,
173+ runtime_status_heartbeat_task,
174+ )
129175}
130176
131177async fn push_definitions_until_success ( config : & Config ) {
@@ -165,7 +211,7 @@ fn runtime_features() -> Vec<RuntimeFeature> {
165211 } ]
166212}
167213
168- async fn update_stopped_status ( runtime_status_service : Option < & TaurusRuntimeStatusService > ) {
214+ async fn update_stopped_status ( runtime_status_service : Option < & Arc < TaurusRuntimeStatusService > > ) {
169215 if let Some ( status_service) = runtime_status_service {
170216 status_service
171217 . update_runtime_status ( tucana:: shared:: execution_runtime_status:: Status :: Stopped )
0 commit comments