Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78c514ff8a | ||
|
|
0138e4659e | ||
|
|
a55dc98487 |
No files matched your search
@@ -163,65 +163,3 @@ jobs:
|
|||||||
run: cp .env.example .env
|
run: cp .env.example .env
|
||||||
- name: Build
|
- name: Build
|
||||||
run: pnpm turbo build --affected
|
run: pnpm turbo build --affected
|
||||||
|
|
||||||
memory-regression:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 15
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v4
|
|
||||||
- name: Build Docker image
|
|
||||||
uses: docker/build-push-action@v7
|
|
||||||
with:
|
|
||||||
platforms: linux/amd64
|
|
||||||
context: .
|
|
||||||
push: false
|
|
||||||
load: true
|
|
||||||
tags: homarr-memory-test
|
|
||||||
network: host
|
|
||||||
cache-from: type=gha
|
|
||||||
cache-to: type=gha,mode=max
|
|
||||||
env:
|
|
||||||
SKIP_ENV_VALIDATION: true
|
|
||||||
- name: Start container and measure memory
|
|
||||||
run: |
|
|
||||||
docker run -d --name homarr-mem-test -p 17575:7575 homarr-memory-test
|
|
||||||
# Wait for container to be healthy (up to 60s)
|
|
||||||
healthy=false
|
|
||||||
for i in $(seq 1 30); do
|
|
||||||
if curl -sf http://localhost:17575/api/health 2>/dev/null; then
|
|
||||||
echo "Container healthy after $((i * 2))s"
|
|
||||||
healthy=true
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
sleep 2
|
|
||||||
done
|
|
||||||
if [ "$healthy" != "true" ]; then
|
|
||||||
echo "ERROR: Container never became healthy"
|
|
||||||
docker logs homarr-mem-test --tail 50
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# Warm up: hit the dashboard page a few times
|
|
||||||
for i in $(seq 1 5); do
|
|
||||||
curl -sf http://localhost:17575/ > /dev/null 2>&1 || true
|
|
||||||
sleep 2
|
|
||||||
done
|
|
||||||
# Measure RSS after warmup
|
|
||||||
MEM_KB=$(docker stats --no-stream --format '{{.MemUsage}}' homarr-mem-test | sed 's| /.*||')
|
|
||||||
echo "Raw memory: $MEM_KB"
|
|
||||||
# Convert to numeric MB (handles GiB and MiB suffixes)
|
|
||||||
MEM_NUM=$(echo "$MEM_KB" | awk '{
|
|
||||||
if ($0 ~ /GiB/) { gsub(/GiB/,""); print $1 * 1024 }
|
|
||||||
else if ($0 ~ /MiB/) { gsub(/MiB/,""); print $1 }
|
|
||||||
else if ($0 ~ /KiB/) { gsub(/KiB/,""); print $1 / 1024 }
|
|
||||||
else { print $1 / 1048576 }
|
|
||||||
}')
|
|
||||||
echo "Memory usage: ${MEM_NUM} MB"
|
|
||||||
MAX_MB=700
|
|
||||||
if awk "BEGIN {exit !($MEM_NUM > $MAX_MB)}"; then
|
|
||||||
echo "ERROR: Memory usage ${MEM_NUM} MB exceeds ${MAX_MB} MB threshold"
|
|
||||||
docker logs homarr-mem-test --tail 50
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "Memory check passed: ${MEM_NUM} MB <= ${MAX_MB} MB"
|
|
||||||
@@ -72,7 +72,14 @@ export const AppForm = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
form.initialize(toFormValues(initialValues));
|
form.initialize(toFormValues(initialValues));
|
||||||
}, [initialValuesKey, form, initialValues]);
|
// `form` is a new object every render (Mantine useForm returns a fresh literal),
|
||||||
|
// so it must not be a dep here — it would re-run every render and, since
|
||||||
|
// form.initialize() always calls clearErrors() (new {} object) internally,
|
||||||
|
// trigger an infinite update loop. initialValuesKey (a primitive string)
|
||||||
|
// already captures the only case this effect exists for: re-initializing
|
||||||
|
// when initialValues actually changes (e.g. navigating between edit pages).
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [initialValuesKey]);
|
||||||
|
|
||||||
// Debounce the name value with 200ms delay
|
// Debounce the name value with 200ms delay
|
||||||
const [debouncedName] = useDebouncedValue(form.values.name, 200);
|
const [debouncedName] = useDebouncedValue(form.values.name, 200);
|
||||||
|
|||||||
Reference in new issue
Block a user