MCPcopy Create free account
hub / github.com/Dstack-TEE/dstack / fetch_with_retry

Function fetch_with_retry

gateway/src/proxy/port_policy.rs:167–209  ·  view source on GitHub ↗
(state: &Proxy, instance_id: &str)

Source from the content-addressed store, hash-verified

165}
166
167async fn fetch_with_retry(state: &Proxy, instance_id: &str) {
168 let cfg = &state.config.proxy.port_policy_fetch;
169 let mut attempt = 0u32;
170 let mut backoff = cfg.backoff_initial;
171 loop {
172 let result =
173 match tokio::time::timeout(cfg.timeout, fetch_and_store(state, instance_id)).await {
174 Ok(r) => r,
175 // The Info() RPC took too long. Treat as transient — the CVM
176 // may just be slow to come up.
177 Err(_) => Err(FetchError::Transient(anyhow::anyhow!(
178 "Info() rpc timed out after {:?}",
179 cfg.timeout
180 ))),
181 };
182 match result {
183 Ok(()) => {
184 debug!("port_policy cached for instance {instance_id} (attempt {attempt})");
185 return;
186 }
187 Err(FetchError::Permanent(err)) => {
188 // Either the instance was recycled while queued, or the
189 // agent responded with data we can't parse. Retrying won't
190 // change either; bail.
191 debug!("port_policy fetch for {instance_id}: permanent failure: {err:#}");
192 return;
193 }
194 Err(FetchError::Transient(err)) => {
195 warn!("port_policy fetch for {instance_id} failed (attempt {attempt}): {err:#}");
196 }
197 }
198 if attempt >= cfg.max_retries {
199 warn!(
200 "port_policy fetch for {instance_id} giving up after {} attempts",
201 attempt + 1
202 );
203 return;
204 }
205 tokio::time::sleep(backoff).await;
206 attempt += 1;
207 backoff = (backoff * 2).min(cfg.backoff_max);
208 }
209}
210
211async fn fetch_and_store(state: &Proxy, instance_id: &str) -> Result<(), FetchError> {
212 let (ip, agent_port) = {

Callers 1

spawn_fetcherFunction · 0.85

Calls 1

fetch_and_storeFunction · 0.85

Tested by

no test coverage detected