Commit 5a76f5f1 authored by Jose Diaz-Gonzalez's avatar Jose Diaz-Gonzalez Committed by Jeremy Morrell

fix: handle case where memory.limit_in_bytes is nonsensically large (#531)

* fix: handle case where memory.limit_in_bytes is nonsensically large

In certain CI environments, this value can be misreported, resulting in an invalid initial `MEMORY_AVAILABLE` value. In these cases, we default the max detected memory to 16GB, or slightly larger than a `performance-l` instance.
parent e13779d0
#!/usr/bin/env bash #!/usr/bin/env bash
calculate_concurrency() { calculate_concurrency() {
WEB_CONCURRENCY=${WEB_CONCURRENCY-$((MEMORY_AVAILABLE/WEB_MEMORY))} local available=$1
if (( WEB_CONCURRENCY < 1 )); then local web_memory=$2
WEB_CONCURRENCY=1 local concurrency
elif (( WEB_CONCURRENCY > 200 )); then
concurrency=${WEB_CONCURRENCY-$(($available/$web_memory))}
if (( concurrency < 1 )); then
concurrency=1
elif (( concurrency > 200 )); then
# Ex: This will happen on Dokku on DO # Ex: This will happen on Dokku on DO
WEB_CONCURRENCY=1 concurrency=1
fi fi
echo $WEB_CONCURRENCY echo "$concurrency"
} }
log_concurrency() { log_concurrency() {
...@@ -26,6 +30,18 @@ detect_memory() { ...@@ -26,6 +30,18 @@ detect_memory() {
fi fi
} }
bound_memory() {
local detected=$1
local detected max_detected_memory=14336
# The hardcoded value is 16GB of memory
if (( detected > max_detected_memory )); then
echo "$max_detected_memory"
else
echo "$detected"
fi
}
warn_bad_web_concurrency() { warn_bad_web_concurrency() {
local concurrency=$((MEMORY_AVAILABLE/WEB_MEMORY)) local concurrency=$((MEMORY_AVAILABLE/WEB_MEMORY))
if [ "$concurrency" -gt "200" ]; then if [ "$concurrency" -gt "200" ]; then
...@@ -39,9 +55,10 @@ appropriate for your application." ...@@ -39,9 +55,10 @@ appropriate for your application."
fi fi
} }
export MEMORY_AVAILABLE=${MEMORY_AVAILABLE-$(detect_memory 512)} DETECTED=$(detect_memory 512)
export MEMORY_AVAILABLE=${MEMORY_AVAILABLE-$(bound_memory $DETECTED)}
export WEB_MEMORY=${WEB_MEMORY-512} export WEB_MEMORY=${WEB_MEMORY-512}
export WEB_CONCURRENCY=$(calculate_concurrency) export WEB_CONCURRENCY=$(calculate_concurrency $MEMORY_AVAILABLE $WEB_MEMORY)
warn_bad_web_concurrency warn_bad_web_concurrency
......
...@@ -168,6 +168,48 @@ testBuildData() { ...@@ -168,6 +168,48 @@ testBuildData() {
assertEquals "a=\"this should come first\" foo=\"value with spaces\" test=different-foo" "$(log_build_data)" assertEquals "a=\"this should come first\" foo=\"value with spaces\" test=different-foo" "$(log_build_data)"
} }
testWebConcurrencyProfileScript() {
# this was set when we sourced the WEB_CONCURRENCY.sh file
unset WEB_MEMORY
unset MEMORY_AVAILABLE
unset WEB_CONCURRENCY
# memory in MB of a 2X dyno
assertEquals "512" "$(bound_memory 512)"
# memory in MB of a 2X dyno
assertEquals "1024" "$(bound_memory 1024)"
# memory in MB of a Peformance-M dyno
assertEquals "2560" "$(bound_memory 2560)"
# memory in MB of a Peformance-L dyno
assertEquals "14336" "$(bound_memory 14336)"
# one more MB
assertEquals "14336" "$(bound_memory 14337)"
# On non-Heroku systems `detect_memory` can return non-sensically large values
# In this case, we should bound
assertEquals "14336" "$(bound_memory 1000000)"
# test calculate_concurrency
# 1x
assertEquals "1" "$(calculate_concurrency 512 512)"
# 2x
assertEquals "2" "$(calculate_concurrency 1024 512)"
# Performance-M
assertEquals "5" "$(calculate_concurrency 2560 512)"
# Performance-L
assertEquals "28" "$(calculate_concurrency 14336 512)"
# In case some very large memory available value gets passed in
assertEquals "1" "$(calculate_concurrency 103401 512)"
# of if web memory is set really low
assertEquals "1" "$(calculate_concurrency 512 1)"
}
# mocks # mocks
source "$(pwd)"/test/mocks/stdlib.sh source "$(pwd)"/test/mocks/stdlib.sh
...@@ -176,6 +218,7 @@ source "$(pwd)"/lib/monitor.sh ...@@ -176,6 +218,7 @@ source "$(pwd)"/lib/monitor.sh
source "$(pwd)"/lib/output.sh source "$(pwd)"/lib/output.sh
source "$(pwd)"/lib/kvstore.sh source "$(pwd)"/lib/kvstore.sh
source "$(pwd)"/lib/build-data.sh source "$(pwd)"/lib/build-data.sh
source "$(pwd)"/profile/WEB_CONCURRENCY.sh
# import the testing framework # import the testing framework
source "$(pwd)"/test/shunit2 source "$(pwd)"/test/shunit2
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment