Skip to content

Commit 333eaf6

Browse files
committed
feat: added update for runtime status service to runner
1 parent cd4c197 commit 333eaf6

2 files changed

Lines changed: 106 additions & 5 deletions

File tree

crates/base/src/client/mod.rs

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::time::{SystemTime, UNIX_EPOCH};
22

3-
use tonic::transport::Channel;
3+
use tokio::time::sleep;
4+
use tonic::transport::{Channel, Endpoint};
45
use tucana::{
56
aquila::{
67
RuntimeStatusUpdateRequest, runtime_status_service_client::RuntimeStatusServiceClient,
@@ -9,15 +10,72 @@ use tucana::{
910
shared::{AdapterConfiguration, AdapterRuntimeStatus, RuntimeFeature},
1011
};
1112

12-
struct DracoRuntimeStatusService {
13+
pub struct DracoRuntimeStatusService {
1314
channel: Channel,
1415
identifier: String,
1516
features: Vec<RuntimeFeature>,
1617
configs: Vec<AdapterConfiguration>,
1718
}
1819

20+
const MAX_BACKOFF: u64 = 2000 * 60;
21+
const MAX_RETRIES: i8 = 10;
22+
23+
// Will create a channel and retry if its not possible
24+
pub async fn create_channel_with_retry(channel_name: &str, url: String) -> Channel {
25+
let mut backoff = 100;
26+
let mut retries = 0;
27+
28+
loop {
29+
let channel = match Endpoint::from_shared(url.clone()) {
30+
Ok(c) => {
31+
log::debug!("Creating a new endpoint for the: {} Service", channel_name);
32+
c.connect_timeout(std::time::Duration::from_secs(2))
33+
.timeout(std::time::Duration::from_secs(10))
34+
}
35+
Err(err) => {
36+
panic!(
37+
"Cannot create Endpoint for Service: `{}`. Reason: {:?}",
38+
channel_name, err
39+
);
40+
}
41+
};
42+
43+
match channel.connect().await {
44+
Ok(ch) => {
45+
return ch;
46+
}
47+
Err(err) => {
48+
log::warn!(
49+
"Retry connect to `{}` using url: `{}` failed: {:?}, retrying in {}ms",
50+
channel_name,
51+
url,
52+
err,
53+
backoff
54+
);
55+
sleep(std::time::Duration::from_millis(backoff)).await;
56+
57+
backoff = (backoff * 2).min(MAX_BACKOFF);
58+
retries += 1;
59+
60+
if retries >= MAX_RETRIES {
61+
panic!("Reached max retries to url {}", url)
62+
}
63+
}
64+
}
65+
}
66+
}
1967
impl DracoRuntimeStatusService {
20-
fn new(
68+
pub async fn from_url(
69+
aquila_url: String,
70+
identifier: String,
71+
features: Vec<RuntimeFeature>,
72+
configs: Vec<AdapterConfiguration>,
73+
) -> Self {
74+
let channel = create_channel_with_retry("Aquila", aquila_url).await;
75+
Self::new(channel, identifier, features, configs)
76+
}
77+
78+
pub fn new(
2179
channel: Channel,
2280
identifier: String,
2381
features: Vec<RuntimeFeature>,
@@ -35,7 +93,7 @@ impl DracoRuntimeStatusService {
3593
self.features.push(feat);
3694
}
3795

38-
async fn update_runtime_status_by_status(
96+
pub async fn update_runtime_status_by_status(
3997
&self,
4098
status: tucana::shared::adapter_runtime_status::Status,
4199
) {

crates/base/src/runner.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::{
2+
client::DracoRuntimeStatusService,
23
config::AdapterConfig,
34
store::AdapterStore,
45
traits::{LoadConfig, Server as AdapterServer},
@@ -8,6 +9,7 @@ use std::sync::Arc;
89
use tokio::signal;
910
use tonic::transport::Server;
1011
use tonic_health::pb::health_server::HealthServer;
12+
use tucana::shared::{AdapterConfiguration, RuntimeFeature};
1113

1214
/// Context passed to adapter server implementations containing all shared resources
1315
pub struct ServerContext<C: LoadConfig> {
@@ -23,6 +25,11 @@ pub struct ServerRunner<C: LoadConfig> {
2325
}
2426

2527
impl<C: LoadConfig> ServerRunner<C> {
28+
29+
pub fn get_server_config(&self) -> Arc<C> {
30+
self.context.server_config.clone()
31+
}
32+
2633
pub async fn new<S: AdapterServer<C>>(server: S) -> anyhow::Result<Self> {
2734
env_logger::Builder::from_default_env()
2835
.filter_level(log::LevelFilter::Debug)
@@ -50,11 +57,34 @@ impl<C: LoadConfig> ServerRunner<C> {
5057
})
5158
}
5259

53-
pub async fn serve(self) -> anyhow::Result<()> {
60+
pub async fn serve(
61+
self,
62+
runtime_feature: Vec<RuntimeFeature>,
63+
runtime_config: Vec<AdapterConfiguration>,
64+
) -> anyhow::Result<()> {
5465
let config = self.context.adapter_config.clone();
66+
let mut runtime_status_service: Option<DracoRuntimeStatusService> = None;
67+
5568
log::info!("Starting Draco Variant: {}", config.draco_variant);
5669

5770
if !config.is_static() {
71+
runtime_status_service = Some(
72+
DracoRuntimeStatusService::from_url(
73+
config.aquila_url.clone(),
74+
config.draco_variant.clone(),
75+
runtime_feature,
76+
runtime_config,
77+
)
78+
.await,
79+
);
80+
81+
if let Some(ser) = &runtime_status_service {
82+
ser.update_runtime_status_by_status(
83+
tucana::shared::adapter_runtime_status::Status::NotReady,
84+
)
85+
.await;
86+
};
87+
5888
let definition_service = FlowUpdateService::from_url(
5989
config.aquila_url.clone(),
6090
config.definition_path.as_str(),
@@ -95,6 +125,13 @@ impl<C: LoadConfig> ServerRunner<C> {
95125
} = self;
96126
// Init the adapter server (e.g. create underlying HTTP server)
97127
server.init(&context).await?;
128+
129+
if let Some(ser) = &runtime_status_service {
130+
ser.update_runtime_status_by_status(
131+
tucana::shared::adapter_runtime_status::Status::Running,
132+
)
133+
.await;
134+
};
98135
log::info!("Draco successfully initialized.");
99136

100137
#[cfg(unix)]
@@ -158,6 +195,12 @@ impl<C: LoadConfig> ServerRunner<C> {
158195
}
159196
}
160197
}
198+
if let Some(ser) = &runtime_status_service {
199+
ser.update_runtime_status_by_status(
200+
tucana::shared::adapter_runtime_status::Status::Stopped,
201+
)
202+
.await;
203+
};
161204

162205
log::info!("Draco shutdown complete");
163206
Ok(())

0 commit comments

Comments
 (0)