Skip to content

Commit 37ec36f

Browse files
committed
Analytics and scheduler fixes
1 parent 6f84e86 commit 37ec36f

File tree

2 files changed

+24
-21
lines changed

2 files changed

+24
-21
lines changed

deploy/cloud/setup-scheduler.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ CHECKER_SCHEDULE="${CHECKER_SCHEDULE:-*/3 * * * *}" # Every 3 minutes
1616

1717
# Analytics reports job
1818
REPORTS_JOB="munimetro-reports"
19-
REPORTS_SCHEDULER="munimetro-reports-daily"
20-
REPORTS_SCHEDULE="${REPORTS_SCHEDULE:-0 0 * * *}" # Daily at midnight UTC
19+
REPORTS_SCHEDULER="munimetro-reports-periodic"
20+
REPORTS_SCHEDULE="${REPORTS_SCHEDULE:-*/30 * * * *}" # Every 30 minutes
2121

2222
echo "=========================================="
2323
echo "MuniMetro Cloud Scheduler Setup"
@@ -27,7 +27,7 @@ echo "Region: $REGION"
2727
echo ""
2828
echo "Schedules:"
2929
echo " Status checker: $CHECKER_SCHEDULE (every 3 min)"
30-
echo " Analytics reports: $REPORTS_SCHEDULE (daily midnight UTC)"
30+
echo " Analytics reports: $REPORTS_SCHEDULE (every 30 min)"
3131
echo "=========================================="
3232
echo ""
3333

@@ -100,7 +100,7 @@ gcloud scheduler jobs create http "$REPORTS_SCHEDULER" \
100100
--max-retry-attempts=2 \
101101
--max-backoff=3600s \
102102
--min-backoff=60s \
103-
--description="Generates MuniMetro analytics reports daily at midnight UTC" \
103+
--description="Generates MuniMetro analytics reports every 30 minutes" \
104104
--project="$PROJECT_ID"
105105

106106
echo "✓ Analytics reports scheduler created: $REPORTS_SCHEDULER"
@@ -132,7 +132,7 @@ echo " Target: $CHECKER_JOB"
132132
echo ""
133133
echo " Analytics Reports:"
134134
echo " Name: $REPORTS_SCHEDULER"
135-
echo " Schedule: $REPORTS_SCHEDULE (daily midnight UTC)"
135+
echo " Schedule: $REPORTS_SCHEDULE (every 30 min)"
136136
echo " Target: $REPORTS_JOB"
137137
echo ""
138138
echo "View scheduler status:"

lib/analytics.py

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -397,22 +397,27 @@ def get_delay_frequency(days=7):
397397
''', (cutoff,))
398398
total_checks = cursor.fetchone()['total']
399399

400-
# Checks by status
400+
# Status distribution uses best_status (what users actually see on dashboard)
401401
cursor.execute('''
402-
SELECT status, COUNT(*) as count
402+
SELECT best_status, COUNT(*) as count
403403
FROM status_checks
404404
WHERE timestamp >= ?
405-
GROUP BY status
405+
GROUP BY best_status
406406
''', (cutoff,))
407407

408408
by_status = {'green': 0, 'yellow': 0, 'red': 0}
409409
for row in cursor.fetchall():
410-
by_status[row['status']] = row['count']
410+
by_status[row['best_status']] = row['count']
411+
412+
# Delay tracking uses raw status (actual delay detections, regardless of smoothing)
413+
cursor.execute('''
414+
SELECT COUNT(*) as count FROM status_checks
415+
WHERE timestamp >= ? AND status = 'yellow'
416+
''', (cutoff,))
417+
delayed_checks = cursor.fetchone()['count']
411418

412419
conn.close()
413420

414-
# Only count yellow as delayed - red is after-hours maintenance
415-
delayed_checks = by_status['yellow']
416421
delay_rate = delayed_checks / total_checks if total_checks > 0 else 0.0
417422

418423
return {
@@ -609,22 +614,20 @@ def get_analytics_report(days=7):
609614
except (json.JSONDecodeError, ValueError):
610615
cached = None
611616

612-
# Check if cache is fresh
617+
# Always return cached data if it exists (never return empty if we have data)
613618
if cached:
619+
cached['from_cache'] = True
614620
try:
615621
cached_at = datetime.fromisoformat(cached.get('cached_at', ''))
616622
cache_age = (datetime.now() - cached_at).total_seconds()
617-
618-
if cache_age < REPORT_CACHE_MAX_AGE:
619-
# Return cached report with cache info
620-
cached['from_cache'] = True
621-
cached['cache_age'] = round(cache_age, 1)
622-
return cached
623+
cached['cache_age'] = round(cache_age, 1)
624+
cached['cache_stale'] = cache_age >= REPORT_CACHE_MAX_AGE
623625
except (ValueError, KeyError):
624-
pass # Cache corrupted or missing timestamp
626+
cached['cache_age'] = None
627+
cached['cache_stale'] = True
628+
return cached
625629

626-
# No fresh cache - return empty report
627-
# Reports are generated by scheduled task, not on-demand
630+
# No cache at all - return empty report
628631
return _empty_report(days)
629632

630633

0 commit comments

Comments
 (0)