polyfill2 0.3.0

Polymarket CLOB V2 Rust client (fork of polyfill-rs). High-performance, EIP-712 signing, WebSocket streaming.
Documentation
//! HTTP client optimization for low-latency trading
//!
//! This module provides optimized HTTP client configurations specifically
//! designed for high-frequency trading environments where every millisecond counts.

use reqwest::{Client, ClientBuilder};
use std::time::Duration;

/// Connection pre-warming helper
pub async fn prewarm_connections(client: &Client, base_url: &str) -> Result<(), reqwest::Error> {
    // Make a few lightweight requests to establish connections
    let endpoints = vec!["/ok", "/time"];

    for endpoint in endpoints {
        let _ = client
            .get(format!("{}{}", base_url, endpoint))
            .timeout(Duration::from_millis(1000))
            .send()
            .await;
    }

    Ok(())
}

/// Create an optimized HTTP client for low-latency trading
/// Benchmarked configuration: 309.3ms vs 349ms baseline (11.4% faster)
pub fn create_optimized_client() -> Result<Client, reqwest::Error> {
    ClientBuilder::new()
        // Avoid reading OS proxy settings (can be slow and/or unavailable in some sandboxed envs)
        .no_proxy()
        // Connection pooling optimizations - aggressive reuse
        .pool_max_idle_per_host(10) // Keep connections alive
        .pool_idle_timeout(Duration::from_secs(90)) // Longer reuse window
        // TCP optimizations
        .tcp_nodelay(true) // Disable Nagle's algorithm for lower latency
        // HTTP/2 optimizations - empirically tuned
        .http2_adaptive_window(true) // Dynamically adjust flow control
        .http2_initial_stream_window_size(512 * 1024) // 512KB - benchmarked optimal
        // Compression - all algorithms enabled by default in reqwest
        .gzip(true) // Ensure gzip is enabled
        // User agent for identification
        .user_agent(concat!(
            "polyfill-rs/",
            env!("CARGO_PKG_VERSION"),
            " (high-frequency-trading)"
        ))
        .build()
}

/// Create a client optimized for co-located environments
/// (even more aggressive settings for when you're close to the exchange)
pub fn create_colocated_client() -> Result<Client, reqwest::Error> {
    ClientBuilder::new()
        // Avoid reading OS proxy settings (can be slow and/or unavailable in some sandboxed envs)
        .no_proxy()
        // More aggressive connection pooling
        .pool_max_idle_per_host(20) // More connections
        .pool_idle_timeout(Duration::from_secs(60)) // Longer reuse
        // Tighter timeouts for co-located environments
        .connect_timeout(Duration::from_millis(1000)) // 1s connection
        .timeout(Duration::from_millis(10000)) // 10s total
        // TCP optimizations
        .tcp_nodelay(true)
        .tcp_keepalive(Duration::from_secs(30))
        // HTTP/2 with more aggressive keep-alive
        .http2_adaptive_window(true)
        .http2_keep_alive_interval(Duration::from_secs(10))
        .http2_keep_alive_timeout(Duration::from_secs(5))
        .http2_keep_alive_while_idle(true)
        // Disable compression in co-located environments (CPU vs network tradeoff)
        .gzip(false)
        .no_brotli() // Disable brotli compression
        .user_agent(concat!(
            "polyfill-rs/",
            env!("CARGO_PKG_VERSION"),
            " (colocated-hft)"
        ))
        .build()
}

/// Create a client optimized for high-latency environments
/// (more conservative settings for internet connections)
pub fn create_internet_client() -> Result<Client, reqwest::Error> {
    ClientBuilder::new()
        // Avoid reading OS proxy settings (can be slow and/or unavailable in some sandboxed envs)
        .no_proxy()
        // Conservative connection pooling
        .pool_max_idle_per_host(5)
        .pool_idle_timeout(Duration::from_secs(90))
        // Longer timeouts for internet connections
        .connect_timeout(Duration::from_millis(10000)) // 10s connection
        .timeout(Duration::from_millis(60000)) // 60s total
        // TCP optimizations
        .tcp_nodelay(true)
        .tcp_keepalive(Duration::from_secs(120))
        // HTTP/1.1 might be more reliable over internet
        .http1_title_case_headers()
        // Enable compression (gzip and brotli are enabled by default)
        .gzip(true)
        .user_agent(concat!(
            "polyfill-rs/",
            env!("CARGO_PKG_VERSION"),
            " (internet-trading)"
        ))
        .build()
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_optimized_client_creation() {
        let client = create_optimized_client();
        assert!(client.is_ok());
    }

    #[test]
    fn test_colocated_client_creation() {
        let client = create_colocated_client();
        assert!(client.is_ok());
    }

    #[test]
    fn test_internet_client_creation() {
        let client = create_internet_client();
        assert!(client.is_ok());
    }
}