solana-shadow 0.2.4

Synchronized shadow state of Solana programs available for off-chain processing.
Documentation
use std::time::Duration;

use tokio::net::TcpStream;
use tokio_tungstenite::{
  tungstenite::{self, client::IntoClientRequest, handshake::client::Response},
  MaybeTlsStream, WebSocketStream,
};
use tracing_futures::Instrument;
use tungstenite::error::Error;

#[tracing::instrument]
pub async fn connect_async<R>(
  timeout: Duration,
  request: R,
) -> Result<(WebSocketStream<MaybeTlsStream<TcpStream>>, Response), Error>
where
  R: std::fmt::Debug + IntoClientRequest + Unpin + Clone,
{
  let mut delay = 500;
  loop {
    match tokio::time::timeout(
      timeout,
      tokio_tungstenite::connect_async(request.clone())
        .instrument(tracing::info_span!("tungstenite_connect_async")),
    )
    .await
    {
      Err(e) => {
        tracing::warn!(
          error=?e, "timeout while trying to connect to websocket, retrying in {}", delay
        );
      }
      Ok(result) => match result {
        Ok(r) => {
          return Ok(r);
        }
        Err(e) => {
          tracing::warn!(error=?e, "websocket connection error, retrying in {}", delay);
        }
      },
    }
    tokio::time::sleep(Duration::from_millis(delay)).await;
    delay = std::cmp::min(8000, delay * 2);
  }
}