Overview
EmptyClassroom allows you to manually refresh classroom availability data to get the most up-to-date information from Boston University’s scheduling system. The refresh feature includes a 30-minute cooldown period to prevent excessive API calls.How to Refresh Data
Check the last updated time
Look at the top of the page where it displays “Last updated [time]”. This shows when the data was last refreshed.
Wait for the update
The button will show ”↻ Refreshing…” and pulse while fetching new data. This typically takes a few seconds.
The 30-Minute Cooldown
What Is It?
The refresh feature has a built-in cooldown period of 30 minutes between refreshes. This prevents overloading the university’s scheduling system while ensuring data stays reasonably current.The cooldown is configured in
backend/config.py:14 as REFRESH_COOLDOWN_MINUTES = 30.How It Works
First refresh
When you click refresh, the system fetches fresh data from BU’s scheduling API and updates the classroom availability.
Button disabled
The refresh button becomes disabled and changes to a gray color indicating it’s not clickable.
Visual Indicators
The refresh button has several states to communicate its status:| State | Appearance | Description |
|---|---|---|
| Ready | Gray text, clickable | Ready to refresh data |
| Refreshing | ”↻ Refreshing…” with pulse animation | Actively fetching new data |
| Cooldown | Gray text, disabled, not clickable | Waiting for cooldown to expire |
| Loading | Gray text, disabled | Checking cooldown status on page load |
When hovering over the disabled refresh button during cooldown, you’ll see exactly how many minutes remain before you can refresh again.
Automatic Refresh on Wake
EmptyClassroom has intelligent wake-up behavior:When Does It Happen?
The app automatically refreshes data when:- The server starts up and no data was fetched today
- The app was sleeping and wakes up on a new day
- There’s no cached data available in Redis
Implementation
The wake-up logic is inbackend/main.py:22:
Wake-up refreshes don’t count against the 30-minute cooldown. They only happen once per day when the server starts.
API Endpoints
The refresh system uses three backend endpoints:POST /api/refresh
Triggers a manual refresh of classroom data. Response on success (200):GET /api/cooldown-status
Checks the current cooldown status. Response:GET /api/last-updated
Returns the timestamp of the last refresh. Response:Frontend Implementation
The refresh functionality is implemented in two main components:RefreshButton Component
Location:frontend/app/components/RefreshButton.tsx:1
Props:
isRefreshing: Boolean indicating active refreshisCooldownLoading: Boolean for initial cooldown checkcooldownRemaining: Number of minutes left in cooldownonRefresh: Callback function to trigger refresh
- Disabled state when
cooldownRemaining > 0 - Hover tooltip showing remaining cooldown time
- Pulse animation during refresh
- Clean visual feedback for all states
Page Component State
Location:frontend/app/page.tsx:65
The main page component manages:
- Fetching cooldown status on mount
- Handling refresh button clicks
- Parsing cooldown time from error responses
- Real-time countdown timer
- Updating UI after successful refresh
Cooldown Timer Behavior
The frontend includes a real-time countdown timer:Data Caching
Refreshed data is cached in Redis:- Cache key:
classrooms:availability - Expiration: 24 hours (86,400 seconds)
- Storage format: JSON string
- Timestamp key:
classrooms:last_refresh
Cache Strategy
- Manual refresh updates the cache immediately
- Cache persists for 24 hours even if not refreshed
- On cache miss, fresh data is fetched automatically
- Last refresh timestamp tracks cooldown separately from cache expiry
Troubleshooting
Refresh button is disabled
Refresh button is disabled
Refresh seems stuck on 'Refreshing...'
Refresh seems stuck on 'Refreshing...'
This could indicate a network issue or API timeout. Refresh the page to reset the state. The backend likely completed the refresh even if the frontend didn’t receive confirmation.
Last updated time doesn't match my refresh
Last updated time doesn't match my refresh
If you see an older timestamp, the refresh may have failed due to the cooldown. Check the browser console for error messages, or wait for the cooldown to expire.
Getting '429 Too Many Requests' error
Getting '429 Too Many Requests' error
You’ve triggered the cooldown protection. This is expected behavior when refreshing too frequently. Wait the indicated number of minutes before trying again.
Technical Details
Timezone Handling
All timestamps use Eastern Time (America/New_York):- Ensures consistency with BU’s academic schedule
- Cooldown calculations account for timezone
- Frontend displays local time but backend uses ET
Redis Integration
The cooldown system relies on Redis for persistence:- Survives server restarts
- Shared across multiple server instances
- Automatic expiration prevents stale cooldowns
Error Handling
The system gracefully handles various failure scenarios:- Redis connection failures default to allowing refresh
- API errors don’t break the cooldown timer
- Missing cache triggers automatic refresh
- Malformed timestamps default to allowing refresh
For developers: The
REFRESH_COOLDOWN_MINUTES constant can be adjusted in config.py, but the default 30 minutes balances freshness with responsible API usage.