-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(transport): wip endpoint rotation
- Loading branch information
Showing
11 changed files
with
410 additions
and
115 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
use std::sync::atomic::{AtomicBool, Ordering}; | ||
use std::sync::Arc; | ||
|
||
use everscale_types::models::*; | ||
use everscale_types::prelude::*; | ||
use nekoton_core::transport::{ContractState, Transport}; | ||
use parking_lot::Mutex; | ||
|
||
use crate::endpoint::Connection; | ||
use crate::models::Timings; | ||
use crate::LiveCheckResult; | ||
|
||
#[derive(Clone)] | ||
pub struct JrpcClient { | ||
client: reqwest::Client, | ||
Check warning on line 15 in transport/src/endpoint/jrpc.rs
|
||
endpoint: Arc<String>, | ||
was_dead: Arc<AtomicBool>, | ||
stats: Arc<Mutex<Option<Timings>>>, | ||
} | ||
|
||
#[async_trait::async_trait] | ||
impl Connection for JrpcClient { | ||
fn new(endpoint: String, client: reqwest::Client) -> Self { | ||
JrpcClient { | ||
client, | ||
endpoint: Arc::new(endpoint), | ||
was_dead: Arc::new(AtomicBool::new(false)), | ||
stats: Arc::new(Default::default()), | ||
} | ||
} | ||
|
||
fn endpoint(&self) -> &str { | ||
self.endpoint.as_str() | ||
} | ||
|
||
fn get_stats(&self) -> Option<Timings> { | ||
self.stats.lock().clone() | ||
} | ||
|
||
fn set_stats(&self, stats: Option<Timings>) { | ||
*self.stats.lock() = stats; | ||
} | ||
|
||
fn update_was_dead(&self, is_dead: bool) { | ||
self.was_dead.store(is_dead, Ordering::Release); | ||
} | ||
|
||
async fn is_alive_inner(&self) -> LiveCheckResult { | ||
todo!() | ||
} | ||
} | ||
|
||
#[async_trait::async_trait] | ||
impl Transport for JrpcClient { | ||
async fn broadcast_message(&self, message: &DynCell) -> anyhow::Result<()> { | ||
Check warning on line 55 in transport/src/endpoint/jrpc.rs
|
||
todo!() | ||
} | ||
|
||
async fn get_contract_state(&self, address: &StdAddr) -> anyhow::Result<ContractState> { | ||
Check warning on line 59 in transport/src/endpoint/jrpc.rs
|
||
todo!() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
use crate::models::Timings; | ||
use crate::LiveCheckResult; | ||
use everscale_types::cell::DynCell; | ||
use everscale_types::models::StdAddr; | ||
use nekoton_core::transport::{ContractState, Transport}; | ||
|
||
mod jrpc; | ||
|
||
#[derive(Clone)] | ||
pub enum Endpoint { | ||
Jrpc(jrpc::JrpcClient), | ||
} | ||
|
||
#[async_trait::async_trait] | ||
impl Transport for Endpoint { | ||
async fn broadcast_message(&self, message: &DynCell) -> anyhow::Result<()> { | ||
match &self { | ||
Endpoint::Jrpc(client) => client.broadcast_message(message).await, | ||
} | ||
} | ||
|
||
async fn get_contract_state(&self, address: &StdAddr) -> anyhow::Result<ContractState> { | ||
match &self { | ||
Endpoint::Jrpc(client) => client.get_contract_state(address).await, | ||
} | ||
} | ||
} | ||
|
||
impl Eq for Endpoint {} | ||
|
||
impl PartialEq<Self> for Endpoint { | ||
fn eq(&self, other: &Self) -> bool { | ||
self.endpoint() == other.endpoint() | ||
} | ||
} | ||
|
||
impl PartialOrd<Self> for Endpoint { | ||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { | ||
Some(self.cmp(other)) | ||
} | ||
} | ||
|
||
impl Ord for Endpoint { | ||
fn cmp(&self, other: &Self) -> std::cmp::Ordering { | ||
if self.eq(other) { | ||
std::cmp::Ordering::Equal | ||
} else { | ||
let left_stats = self.get_stats(); | ||
let right_stats = other.get_stats(); | ||
|
||
match (left_stats, right_stats) { | ||
(Some(left_stats), Some(right_stats)) => left_stats.cmp(&right_stats), | ||
(None, Some(_)) => std::cmp::Ordering::Less, | ||
(Some(_), None) => std::cmp::Ordering::Greater, | ||
(None, None) => std::cmp::Ordering::Equal, | ||
} | ||
} | ||
} | ||
} | ||
|
||
#[async_trait::async_trait] | ||
pub trait Connection: Send + Sync { | ||
fn new(endpoint: String, client: reqwest::Client) -> Self; | ||
|
||
async fn is_alive(&self) -> bool { | ||
let check_result = self.is_alive_inner().await; | ||
let is_alive = check_result.as_bool(); | ||
self.update_was_dead(!is_alive); | ||
|
||
match check_result { | ||
LiveCheckResult::Live(stats) => self.set_stats(Some(stats)), | ||
LiveCheckResult::Dummy => {} | ||
LiveCheckResult::Dead => {} | ||
} | ||
|
||
is_alive | ||
} | ||
|
||
fn endpoint(&self) -> &str; | ||
|
||
fn get_stats(&self) -> Option<Timings>; | ||
|
||
fn set_stats(&self, stats: Option<Timings>); | ||
|
||
fn update_was_dead(&self, is_dead: bool); | ||
|
||
async fn is_alive_inner(&self) -> LiveCheckResult; | ||
} | ||
|
||
#[async_trait::async_trait] | ||
impl Connection for Endpoint { | ||
fn new(endpoint: String, client: reqwest::Client) -> Self { | ||
// TODO: parse url to determine type of connection | ||
Self::Jrpc(jrpc::JrpcClient::new(endpoint, client)) | ||
} | ||
|
||
async fn is_alive(&self) -> bool { | ||
match &self { | ||
Endpoint::Jrpc(client) => client.is_alive().await, | ||
} | ||
} | ||
|
||
fn endpoint(&self) -> &str { | ||
match &self { | ||
Endpoint::Jrpc(client) => client.endpoint(), | ||
} | ||
} | ||
|
||
fn get_stats(&self) -> Option<Timings> { | ||
match &self { | ||
Endpoint::Jrpc(client) => client.get_stats(), | ||
} | ||
} | ||
|
||
fn set_stats(&self, stats: Option<Timings>) { | ||
match &self { | ||
Endpoint::Jrpc(client) => client.set_stats(stats), | ||
} | ||
} | ||
|
||
fn update_was_dead(&self, is_dead: bool) { | ||
match &self { | ||
Endpoint::Jrpc(client) => client.update_was_dead(is_dead), | ||
} | ||
} | ||
|
||
async fn is_alive_inner(&self) -> LiveCheckResult { | ||
match &self { | ||
Endpoint::Jrpc(client) => client.is_alive_inner().await, | ||
} | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.