use std::{collections::HashMap, sync::Arc, time::Duration};
use crate::query_planner::planner::plan_nodes::CustomScalarPaths;
use async_trait::async_trait;
use futures::stream::BoxStream;
use http::{HeaderMap, Uri};
use sonic_rs::Value;
use crate::executor::{
executors::error::SubgraphExecutorError, plugin_context::PluginRequestState,
response::subgraph_response::SubgraphResponse,
};
#[async_trait]
pub trait SubgraphExecutor {
fn executor_name(&self) -> &str;
fn endpoint(&self) -> &Uri;
async fn execute<'a>(
&self,
execution_request: SubgraphExecutionRequest<'a>,
timeout: Option<Duration>,
plugin_req_state: Option<&'a PluginRequestState<'a>>,
) -> Result<SubgraphResponse<'static>, SubgraphExecutorError>;
async fn subscribe<'a>(
&self,
execution_request: SubgraphExecutionRequest<'a>,
timeout: Option<Duration>,
) -> Result<
BoxStream<'static, Result<SubgraphResponse<'static>, SubgraphExecutorError>>,
SubgraphExecutorError,
>;
fn to_boxed_arc<'a>(self) -> Arc<Box<dyn SubgraphExecutor + Send + Sync + 'a>>
where
Self: Sized + Send + Sync + 'a,
{
Arc::new(Box::new(self))
}
}
pub type SubgraphExecutorType =
dyn crate::executor::executors::common::SubgraphExecutor + Send + Sync;
pub type SubgraphExecutorBoxedArc = Arc<Box<SubgraphExecutorType>>;
pub type SubgraphRequestExtensions = HashMap<String, Value>;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct ConnectionFingerprint(u64);
impl ConnectionFingerprint {
pub fn from_hash(hash: u64) -> Self {
Self(hash)
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct InboundRequestFingerprint(u64);
impl InboundRequestFingerprint {
pub fn from_hash(hash: u64) -> Self {
Self(hash)
}
}
pub struct SubgraphExecutionRequest<'a> {
pub query: &'a str,
pub document_name_write_pos: usize,
pub dedupe: bool,
pub operation_name: Option<String>,
pub variables: Option<HashMap<&'a str, &'a sonic_rs::Value>>,
pub headers: HeaderMap,
pub raw_variable_values: Option<Vec<(&'a str, Vec<u8>)>>,
pub extensions: Option<SubgraphRequestExtensions>,
pub custom_scalar_paths: Option<&'a CustomScalarPaths>,
pub connection_fingerprint: Option<ConnectionFingerprint>,
}
impl SubgraphExecutionRequest<'_> {
pub fn add_request_extensions_field(&mut self, key: String, value: Value) {
self.extensions
.get_or_insert_with(HashMap::new)
.insert(key, value);
}
}