# HAProxy frontend configuration for Feersum
# Usage: haproxy -f /path/to/haproxy-frontend.cfg
#
# =============================================================================
# BACKEND OPTIONS
# =============================================================================
#
# 1. PSGI with Plack::Handler::Feersum (simple)
#    TCP:  plackup -s Feersum -p 5000 --keepalive app.psgi
#    Unix: plackup -s Feersum -l /tmp/feersum.sock --keepalive app.psgi
#
# 2. PSGI with Server::Starter + Plack::Handler::Feersum::SS (hot restart)
#    TCP:  start_server --port 5000 -- \
#            plackup -s Feersum::SS -E production \
#            --keepalive --header-timeout 30 app.psgi
#    Unix: start_server --path /tmp/feersum.sock -- \
#            plackup -s Feersum::SS -E production \
#            --keepalive --header-timeout 30 app.psgi
#
#    Hot restart: kill -HUP $(cat /path/to/start_server.pid)
#
# 3. Native interface (maximum performance)
#    See eg/native.pl for full example:
#    perl eg/native.pl 5000
#
#    Inline example:
#    perl -MFeersum -MIO::Socket::INET -e '
#        my $sock = IO::Socket::INET->new(
#            LocalAddr => "127.0.0.1:5000", ReuseAddr => 1, Listen => 1024
#        ) or die $!;
#        my $f = Feersum->endjinn;
#        $f->use_socket($sock);
#        $f->set_keepalive(1);
#        $f->header_timeout(30);
#        $f->request_handler(sub {
#            shift->send_response(200, ["Content-Type","text/plain"], "OK");
#        });
#        EV::run;'
#
# 4. Native with Server::Starter (hot restart + native performance)
#    start_server --port 5000 --backlog 4096 -- \
#      perl -MFeersum -MServer::Starter=server_ports -e '
#        my ($port, $fd) = each %{server_ports()};
#        open(my $sock, "<&=", $fd) or die $!;
#        my $f = Feersum->endjinn;
#        $f->use_socket($sock);
#        $f->set_keepalive(1);
#        $f->header_timeout(30);
#        $f->request_handler(sub { shift->send_response(200, [], "OK") });
#        EV::run;'
#
# BACKLOG TUNING:
#   Feersum uses SOMAXCONN (typically 128) as listen backlog.
#   For high-traffic servers, increase at OS level:
#     Linux:   sysctl -w net.core.somaxconn=4096
#     FreeBSD: sysctl kern.ipc.somaxconn=4096
#   With Server::Starter, use --backlog option as shown above.
#
# =============================================================================

global
    log stdout format raw local0
    maxconn 4096
    # Unix socket for stats (optional)
    stats socket /tmp/haproxy.sock mode 660 level admin

defaults
    log     global
    mode    http
    option  httplog
    option  dontlognull
    option  forwardfor
    option  http-keep-alive

    # Timeouts (Slowloris protection)
    timeout connect 5s
    timeout client  30s
    timeout server  60s
    timeout http-request 30s
    timeout http-keep-alive 60s

    # Retries
    retries 3
    option  redispatch

#=============================================================================
# Frontend: Accept client connections
#=============================================================================
frontend http_front
    bind *:80
    bind :::80

    # Optional: HTTPS with SSL termination
    # bind *:443 ssl crt /etc/ssl/certs/server.pem alpn h2,http/1.1

    # Rate limiting (optional, Slowloris protection)
    stick-table type ip size 100k expire 30s store conn_rate(10s)
    http-request track-sc0 src
    http-request deny if { sc_conn_rate(0) gt 100 }

    # Request size limit
    http-request deny if { req.body_size gt 104857600 }

    # Add headers for backend
    http-request set-header X-Forwarded-Proto %[ssl_fc,iif(https,http)]
    http-request set-header X-Real-IP %[src]

    # Route to backend
    default_backend feersum_tcp
    # Or use Unix socket:
    # default_backend feersum_unix

#=============================================================================
# Backend: TCP connection to Feersum
#=============================================================================
backend feersum_tcp
    balance roundrobin
    option httpchk GET /health

    # HTTP/1.1 keepalive to backend
    option http-keep-alive
    http-reuse safe

    # Connection pooling
    default-server maxconn 256 check inter 5s fall 3 rise 2

    # Single server (add more for load balancing)
    server feersum1 127.0.0.1:5000 check
    # server feersum2 127.0.0.1:5001 check
    # server feersum3 127.0.0.1:5002 check

#=============================================================================
# Backend: Unix socket connection to Feersum (faster)
#=============================================================================
backend feersum_unix
    balance roundrobin

    # HTTP/1.1 keepalive to backend
    option http-keep-alive
    http-reuse safe

    # Unix socket server
    server feersum_local /tmp/feersum.sock check

#=============================================================================
# Backend: Multiple Feersum workers with SO_REUSEPORT
#=============================================================================
backend feersum_reuseport
    balance roundrobin
    option http-keep-alive
    http-reuse safe

    # All workers share the same port via SO_REUSEPORT
    # Start with: plackup -s Feersum -p 5000 --pre-fork 4 --reuseport --keepalive
    server feersum 127.0.0.1:5000 check

#=============================================================================
# Stats page (optional)
#=============================================================================
frontend stats
    bind *:8404
    stats enable
    stats uri /stats
    stats refresh 10s
    stats auth admin:password
