#!/bin/bash

# Modeled closely after flask portion of amazon/aws-eb-python:3.4.2-onbuild-3.5.1 entrypoint script

UWSGI_NUM_PROCESSES='1'
UWSGI_NUM_THREADS='15'
UWSGI_UID='uwsgi'
UWSGI_GID='uwsgi'
# increase header buffer size if one is seeing 502s & 'invalid request block size' errors in uwsgi log
UWSGI_BUFFER_SIZE='12288'
UWSGI_HEADERS='Connection:Keep-Alive'
UWSGI_LOGGING='--log-4xx --log-5xx --log-ioerror --log-x-forwarded-for --disable-logging'
. env/bin/activate

# Flask support
if cat pyproject.toml | grep -q -i Flask && [ -z "${WSGI_MODULE}" ]; then
  UWSGI_MODULE='--module application:app'
fi

# defaulting to application.py if not explicitly set
[ -z "${WSGI_PATH}" ] && WSGI_PATH=application.py

# The timeout ladder fits under the edge load balancer, whose idle timeout is 60s (the
# terraform-fargate default for this service): Prod p99 is ~2s and the slowest 
# legitimate request is ~27s, so every layer sits well above real traffic.
#
#   LB > http-timeout > harakiri > longest downstream read (e.g., Snowflake)
# 
#   http-timeout 58     the --http router connection timeout. Above harakiri (so it never preempts
#                       a worker kill) and below the LB idle timeout.
#   harakiri 55         kill a worker whose request runs past 55s. Above the 50s Snowflake read and
#                       the ~27s observed max, below the LB, so only genuinely stuck workers die.
#   max-requests        recycle each worker after ~5000 requests to bound memory growth from slow
#                       leaks (the 500 jitter de-syncs recycles once UWSGI_NUM_PROCESSES > 1).
#   reload-mercy 30     on reload, give workers 30s to drain in-flight requests before SIGKILL
#                       (a longer in-flight request is dropped on deploy; callers must tolerate it).
#   die-on-term         without this, uWSGI's default is to treat SIGTERM as a reload signal, not a
#                       graceful stop -- which would fight Fargate's SIGTERM-then-SIGKILL shutdown
#                       and drop in-flight requests instead of draining them via reload-mercy.
DDTRACE_BINARY=$(whereis ddtrace-run | cut -d ' ' -f 2)
if [ -x ${DDTRACE_BINARY} ]; then
  ${DDTRACE_BINARY} uwsgi \
    ${UWSGI_LOGGING} \
    --cache2 name=uwsgi_cache,items=10 \
    --http :8080 \
    --chdir /var/app \
    --wsgi-file ${WSGI_PATH} \
    ${UWSGI_MODULE} \
    --master \
    --processes ${UWSGI_NUM_PROCESSES} \
    --threads ${UWSGI_NUM_THREADS} \
    --uid ${UWSGI_UID} \
    --gid ${UWSGI_GID} \
    --buffer-size ${UWSGI_BUFFER_SIZE} \
    --http-keepalive \
    --add-header ${UWSGI_HEADERS} \
    --lazy-apps \
    --http-timeout 58 \
    --harakiri 55 \
    --harakiri-verbose \
    --max-requests 5000 \
    --max-requests-delta 500 \
    --reload-mercy 30 \
    --worker-reload-mercy 30 \
    --die-on-term \
    --import=ddtrace.bootstrap.sitecustomize
else
  /var/app/bin/uwsgi \
    ${UWSGI_LOGGING} \
    --cache2 name=uwsgi_cache,items=10 \
    --http :8080 \
    --chdir /var/app \
    --wsgi-file ${WSGI_PATH} \
    ${UWSGI_MODULE} \
    --master \
    --processes ${UWSGI_NUM_PROCESSES} \
    --threads ${UWSGI_NUM_THREADS} \
    --uid ${UWSGI_UID} \
    --gid ${UWSGI_GID} \
    --buffer-size ${UWSGI_BUFFER_SIZE} \
    --http-keepalive \
    --add-header ${UWSGI_HEADERS} \
    --lazy-apps \
    --http-timeout 58 \
    --harakiri 55 \
    --harakiri-verbose \
    --max-requests 5000 \
    --max-requests-delta 500 \
    --reload-mercy 30 \
    --worker-reload-mercy 30 \
    --die-on-term \
    --import=ddtrace.bootstrap.sitecustomize
fi
