forked from zakaria/chicken-counting-sukawarna-det
Fix dashboard freeze: waitress, reduce frame refresh, atomic reads
- Switch Flask dev server -> waitress (8 threads, production WSGI) - Only refresh frame.jpg when frame_index changes, not every second - Safety try/except on send_file for edge-case file conflicts - Fix test_run.sh: export PYTHONPATH, use venv python - Update service file to use venv python
This commit is contained in:
1 parent
b9f4ba2ef8
commit
6cddf2c9d3
4 files changed
+16
-9
No files matched your search
@@ -6,7 +6,7 @@ After=network.target
|
||||
Type=simple
|
||||
User=dsutanto
|
||||
WorkingDirectory=/media/jetson/DATA/.Codes/chicken-counting-sukawarna-det
|
||||
ExecStart=/usr/bin/python3 dashboard.py --port 8080 --db chicken_counts.db
|
||||
ExecStart=/media/jetson/DATA/karung-sukawarna/venv/bin/python dashboard.py --port 8080 --db chicken_counts.db
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
Environment=PYTHONUNBUFFERED=1
|
||||
|
||||
+7
-4
@@ -14,7 +14,8 @@ import sqlite3
|
||||
import threading
|
||||
from pathlib import Path
|
||||
|
||||
from flask import Flask, Response, jsonify, render_template, send_file
|
||||
from flask import Flask, jsonify, render_template, send_file
|
||||
from waitress import serve
|
||||
|
||||
# Suppress Flask request logs
|
||||
log = logging.getLogger("werkzeug")
|
||||
@@ -103,7 +104,10 @@ def shm_frame(camera_id):
|
||||
frame_path = Path(app.config["shm_dir"]) / f"chicken_counter_{camera_id}" / "frame.jpg"
|
||||
if not frame_path.exists():
|
||||
return jsonify({"error": "not found"}), 404
|
||||
return send_file(frame_path, mimetype="image/jpeg", max_age=0, download_name=None)
|
||||
try:
|
||||
return send_file(frame_path, mimetype="image/jpeg", max_age=2, download_name=None)
|
||||
except (FileNotFoundError, PermissionError):
|
||||
return jsonify({"error": "not ready"}), 503
|
||||
|
||||
|
||||
def _get_db():
|
||||
@@ -205,7 +209,6 @@ def main():
|
||||
parser.add_argument("--poll-ms", type=int, default=500)
|
||||
parser.add_argument("--date", default="", help="Processing date")
|
||||
parser.add_argument("--db", default="chicken_counts.db", help="SQLite database path")
|
||||
parser.add_argument("--debug", action="store_true")
|
||||
args = parser.parse_args()
|
||||
|
||||
app.config["shm_dir"] = args.shm_dir
|
||||
@@ -217,7 +220,7 @@ def main():
|
||||
_init_db(app.config["db_path"])
|
||||
|
||||
print(f"[dashboard] http://0.0.0.0:{args.port} shm={args.shm_dir} db={args.db}" + (f" date={args.date}" if args.date else ""))
|
||||
app.run(host="0.0.0.0", port=args.port, debug=args.debug, threaded=True)
|
||||
serve(app, host="0.0.0.0", port=args.port, threads=8)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -121,11 +121,10 @@ function selectCam(id) {
|
||||
function poll() {
|
||||
if (!activeCam) return;
|
||||
var t = Date.now();
|
||||
var img = document.getElementById("frame-img");
|
||||
img.src = "/shm/" + activeCam + "/frame.jpg?t=" + t;
|
||||
fetch("/shm/" + activeCam + "/stats.json?t=" + t).then(r => r.ok ? r.json() : null).then(s => {
|
||||
if (!s) { setOffline(); return; }
|
||||
lastUpdate = Date.now();
|
||||
var oldFrame = lastFramePerCam[activeCam] || 0;
|
||||
lastFramePerCam[activeCam] = s.frame_index;
|
||||
perCam[activeCam] = { total: s.total_entered_count, inside: s.inside_box_count, frame: s.frame_index, tracks: s.track_count, speed: s.smoothed_speed };
|
||||
document.getElementById("s-total").textContent = s.total_entered_count;
|
||||
@@ -138,6 +137,10 @@ function poll() {
|
||||
tag.textContent = activeCam + " \u2022 " + status;
|
||||
tag.className = "tag " + (s.backward_active ? "off" : "live");
|
||||
document.getElementById("cam-count").textContent = s.total_entered_count;
|
||||
// only refresh frame when index changes (every 5 frames with interval_frames=5)
|
||||
if (s.frame_index != oldFrame) {
|
||||
document.getElementById("frame-img").src = "/shm/" + activeCam + "/frame.jpg?t=" + t;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -1,7 +1,8 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
CMD="PYTHONPATH=/media/jetson/DATA/.Codes/chicken-counting-sukawarna-det/src /media/jetson/DATA/karung-sukawarna/venv/bin/python -m chicken_counter.cli"
|
||||
export PYTHONPATH=/media/jetson/DATA/.Codes/chicken-counting-sukawarna-det/src
|
||||
PYTHON=/media/jetson/DATA/karung-sukawarna/venv/bin/python
|
||||
|
||||
dates=(
|
||||
"2026-06-10" "2026-06-11" "2026-06-12" "2026-06-13" "2026-06-14"
|
||||
@@ -10,5 +11,5 @@ dates=(
|
||||
|
||||
for date in "${dates[@]}"; do
|
||||
echo "=== Processing $date ==="
|
||||
$CMD batch --config configs/cycle7_batch.yaml --date "$date" --no-video
|
||||
$PYTHON -m chicken_counter.cli batch --config configs/cycle7_batch.yaml --date "$date" --no-video
|
||||
done
|
||||
Reference in new issue
Block a user