use std::net::TcpListener;
use miden_remote_prover::error::RemoteProverError;
use pingora::{Error, ErrorType, http::ResponseHeader, protocols::http::ServerSession};
use pingora_proxy::Session;
use tracing::debug;
use crate::{COMPONENT, commands::PROXY_HOST, proxy::metrics::QUEUE_DROP_COUNT};
const RESOURCE_EXHAUSTED_CODE: u16 = 8;
pub(crate) async fn create_queue_full_response(
session: &mut Session,
) -> pingora_core::Result<bool> {
let mut header = ResponseHeader::build(503, None)?;
header.insert_header("grpc-message", "Too many requests in the queue".to_string())?;
header.insert_header("grpc-status", RESOURCE_EXHAUSTED_CODE)?;
session.set_keepalive(None);
session.write_response_header(Box::new(header.clone()), true).await?;
let mut error = Error::new(ErrorType::HTTPStatus(503))
.more_context("Too many requests in the queue")
.into_in();
error.set_cause("Too many requests in the queue");
session.write_response_header(Box::new(header), false).await?;
QUEUE_DROP_COUNT.inc();
Err(error)
}
pub async fn create_too_many_requests_response(
session: &mut Session,
max_request_per_second: isize,
) -> pingora_core::Result<bool> {
let mut header = ResponseHeader::build(429, None)?;
header.insert_header("X-Rate-Limit-Limit", max_request_per_second.to_string())?;
header.insert_header("X-Rate-Limit-Remaining", "0")?;
header.insert_header("X-Rate-Limit-Reset", "1")?;
session.set_keepalive(None);
session.write_response_header(Box::new(header), true).await?;
Ok(true)
}
pub async fn create_response_with_error_message(
session: &mut ServerSession,
error_msg: String,
) -> pingora_core::Result<bool> {
let mut header = ResponseHeader::build(400, None)?;
header.insert_header("X-Error-Message", error_msg)?;
session.set_keepalive(None);
session.write_response_header(Box::new(header)).await?;
Ok(true)
}
pub fn check_port_availability(
port: u16,
service: &str,
) -> Result<std::net::TcpListener, RemoteProverError> {
let addr = format!("{PROXY_HOST}:{port}");
TcpListener::bind(&addr)
.inspect(|_| debug!(target: COMPONENT, %service, %port, %addr, "Port is available"))
.map_err(|err| RemoteProverError::PortAlreadyInUse(err, port))
}