upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/client.rs130
1 files changed, 102 insertions, 28 deletions
diff --git a/src/lib/client.rs b/src/lib/client.rs
index 3b613b6..445bf77 100644
--- a/src/lib/client.rs
+++ b/src/lib/client.rs
@@ -15,11 +15,11 @@ use std::{
15 fmt::{Display, Write}, 15 fmt::{Display, Write},
16 fs::create_dir_all, 16 fs::create_dir_all,
17 path::Path, 17 path::Path,
18 sync::Arc, 18 sync::{Arc, RwLock},
19 time::Duration, 19 time::Duration,
20}; 20};
21 21
22use anyhow::{Context, Result, bail}; 22use anyhow::{Context, Result, anyhow, bail};
23use async_trait::async_trait; 23use async_trait::async_trait;
24use console::Style; 24use console::Style;
25use futures::{ 25use futures::{
@@ -60,6 +60,29 @@ pub struct Client {
60 more_fallback_relays: Vec<String>, 60 more_fallback_relays: Vec<String>,
61 blaster_relays: Vec<String>, 61 blaster_relays: Vec<String>,
62 fallback_signer_relays: Vec<String>, 62 fallback_signer_relays: Vec<String>,
63 relays_not_to_retry: Arc<RwLock<HashMap<RelayUrl, String>>>,
64}
65
66impl Client {
67 /// Marks a relay as skipped for the current session with a given reason.
68 /// This method encapsulates the write lock for the relays_not_to_retry map.
69 fn skip_relay_for_session(&self, relay_url: RelayUrl, reason: String) {
70 self.relays_not_to_retry
71 .write()
72 .unwrap()
73 .insert(relay_url, reason);
74 }
75
76 /// Checks if a relay should be skipped for the current session and returns
77 /// the reason if it is. This method encapsulates the read lock for the
78 /// relays_not_to_retry map.
79 fn is_relay_skipped_for_session(&self, relay_url: &RelayUrl) -> Option<String> {
80 self.relays_not_to_retry
81 .read()
82 .unwrap()
83 .get(relay_url)
84 .cloned()
85 }
63} 86}
64 87
65#[cfg_attr(test, automock)] 88#[cfg_attr(test, automock)]
@@ -127,6 +150,7 @@ impl Connect for Client {
127 more_fallback_relays: opts.more_fallback_relays, 150 more_fallback_relays: opts.more_fallback_relays,
128 blaster_relays: opts.blaster_relays, 151 blaster_relays: opts.blaster_relays,
129 fallback_signer_relays: opts.fallback_signer_relays, 152 fallback_signer_relays: opts.fallback_signer_relays,
153 relays_not_to_retry: Arc::new(RwLock::new(HashMap::new())),
130 } 154 }
131 } 155 }
132 156
@@ -135,6 +159,9 @@ impl Connect for Client {
135 } 159 }
136 160
137 async fn connect(&self, relay_url: &RelayUrl) -> Result<()> { 161 async fn connect(&self, relay_url: &RelayUrl) -> Result<()> {
162 if let Some(reason) = self.is_relay_skipped_for_session(relay_url) {
163 bail!("{reason}");
164 }
138 self.client 165 self.client
139 .add_relay(relay_url) 166 .add_relay(relay_url)
140 .await 167 .await
@@ -150,6 +177,7 @@ impl Connect for Client {
150 } 177 }
151 178
152 if !relay.is_connected() { 179 if !relay.is_connected() {
180 self.skip_relay_for_session(relay_url.clone(), "connection timeout".to_string());
153 bail!("connection timeout"); 181 bail!("connection timeout");
154 } 182 }
155 Ok(()) 183 Ok(())
@@ -244,21 +272,37 @@ impl Connect for Client {
244 } else { 272 } else {
245 None 273 None
246 }; 274 };
275 fn update_progress_bar_with_error(
276 relay_url: &RelayUrl,
277 pb: Option<ProgressBar>,
278 error: &anyhow::Error,
279 ) {
280 if let Some(pb) = pb {
281 pb.set_style(pb_after_style(false));
282 pb.set_prefix(format!("{: <11}{}", "error", relay_url));
283 pb.finish_with_message(
284 console::style(
285 error.to_string().replace("relay pool error:", "error:"),
286 )
287 .for_stderr()
288 .red()
289 .to_string(),
290 );
291 }
292 }
293 if let Some(reason) = self.is_relay_skipped_for_session(relay.url()) {
294 update_progress_bar_with_error(relay.url(), pb, &anyhow!("{reason}"));
295 bail!("{reason}");
296 }
247 #[allow(clippy::large_futures)] 297 #[allow(clippy::large_futures)]
248 match get_events_of(relay, filters, &pb).await { 298 match get_events_of(relay, filters, &pb).await {
249 Err(error) => { 299 Err(error) => {
250 if let Some(pb) = pb { 300 // Check error for timeout/connection issues and add to skip list
251 pb.set_style(pb_after_style(false)); 301 if error.to_string().contains("connection timeout") {
252 pb.set_prefix(format!("{: <11}{}", "error", relay.url())); 302 // Simple check, refine as needed
253 pb.finish_with_message( 303 self.skip_relay_for_session(relay.url().clone(), error.to_string());
254 console::style(
255 error.to_string().replace("relay pool error:", "error:"),
256 )
257 .for_stderr()
258 .red()
259 .to_string(),
260 );
261 } 304 }
305 update_progress_bar_with_error(relay.url(), pb, &error);
262 Err(error) 306 Err(error)
263 } 307 }
264 Ok(res) => { 308 Ok(res) => {
@@ -391,25 +435,55 @@ impl Connect for Client {
391 } else { 435 } else {
392 None 436 None
393 }; 437 };
394 438 // do here
439
440 fn update_progress_bar_with_error(
441 relay_column_width: usize,
442 relay_url: &RelayUrl,
443 pb: Option<ProgressBar>,
444 error: &anyhow::Error,
445 ) {
446 if let Some(pb) = pb {
447 pb.set_style(pb_after_style(false));
448 pb.set_prefix(
449 Style::new()
450 .color256(247)
451 .apply_to(format!("{: <relay_column_width$}", &relay_url))
452 .to_string(),
453 );
454 pb.finish_with_message(
455 console::style(
456 error.to_string().replace("relay pool error:", "error:"),
457 )
458 .for_stderr()
459 .red()
460 .to_string(),
461 );
462 }
463 }
464 if let Some(reason) = self.is_relay_skipped_for_session(&relay_url) {
465 update_progress_bar_with_error(
466 relay_column_width,
467 &relay_url,
468 pb,
469 &anyhow!("{reason}"),
470 );
471 bail!("{reason}");
472 }
395 #[allow(clippy::large_futures)] 473 #[allow(clippy::large_futures)]
396 match self.fetch_all_from_relay(git_repo_path, request, &pb).await { 474 match self.fetch_all_from_relay(git_repo_path, request, &pb).await {
397 Err(error) => { 475 Err(error) => {
398 if let Some(pb) = pb { 476 // Check error for timeout/connection issues and add to skip list
399 pb.set_style(pb_after_style(false)); 477 if error.to_string().contains("connection timeout") {
400 pb.set_prefix( 478 // Simple check, refine as needed
401 dim.apply_to(format!("{: <relay_column_width$}", &relay_url)) 479 self.skip_relay_for_session(relay_url.clone(), error.to_string());
402 .to_string(),
403 );
404 pb.finish_with_message(
405 console::style(
406 error.to_string().replace("relay pool error:", "error:"),
407 )
408 .for_stderr()
409 .red()
410 .to_string(),
411 );
412 } 480 }
481 update_progress_bar_with_error(
482 relay_column_width,
483 &relay_url,
484 pb,
485 &error,
486 );
413 Err(error) 487 Err(error)
414 } 488 }
415 Ok(res) => Ok(res), 489 Ok(res) => Ok(res),