Skip to content

Use async HTTP requests for UI and stats (#835)#845

Open
Eclipse1982 wants to merge 1 commit into
jdolan:mainfrom
Eclipse1982:feature/async-ui-http
Open

Use async HTTP requests for UI and stats (#835)#845
Eclipse1982 wants to merge 1 commit into
jdolan:mainfrom
Eclipse1982:feature/async-ui-http

Conversation

@Eclipse1982

@Eclipse1982 Eclipse1982 commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Replaces the blocking HTTP requests in the UI / stats code paths with asynchronous requests, so the client no longer shows a black screen at launch (GUID hash fetch) or freezes when opening the Leaderboard and Stats menus while waiting on the stats API.

Completion callbacks run on the HTTP session thread; results are staged and marshaled to the main thread via MVC_NOTIFICATION_EVENT, and view controllers refresh in respondToEvent — following the pattern suggested in the issue and already used by NOTIFICATION_SERVER_PARSED.

Fixes #835

Changes

  • Added Net_HttpGetInstanceAsync / Net_HttpGetInstancesAsync — async counterparts to the JSON instance helpers — and exposed them through the cgame import (cgi.HttpGetInstanceAsync, cgi.HttpGetInstancesAsync).
  • Cl_InitGuidHash now fires an async request at startup; the hash is applied to guid_hashed on the main thread via a new NOTIFICATION_GUID_HASHED event, so startup never blocks on the network. The call was moved after Ui_Init, because MVC_NOTIFICATION_EVENT is only registered with SDL once ObjectivelyMVC initializes — a completion firing earlier would push event type 0 and the hash would be silently dropped.
  • LeaderboardViewController fetches asynchronously (initial load and sort-column clicks); rows are staged under a mutex and applied in respondToEvent on NOTIFICATION_LEADERBOARD_FETCHED. It also reloads when the GUID hash arrives so the local player's row highlights.
  • StatsViewController fetches asynchronously, showing placeholders until NOTIFICATION_STATS_FETCHED delivers the response; it refreshes when NOTIFICATION_GUID_HASHED arrives (previously a cold start could show "Sign in" until the next visit).
  • Generation counters discard stale responses when a newer fetch supersedes an in-flight one; callbacks never touch UI state directly, so there are no dangling view controller pointers.
  • Added check_http unit tests covering both new async helpers against the local test HTTP server.

Testing

  • Builds without warnings (make -j$(nproc))
  • Tests pass (make check)
  • Tested in-game on Linux (Debian 12)

Notes

  • Built and tested on Debian 12 with the from-source dependency stack from linux/docker/Dockerfile.build. The changed files compile without warnings (pre-existing warnings elsewhere in the tree are untouched).
  • make check: 18/19 suites pass, including check_http with the two new async tests. The one failure is check_filesystem ("Failed to load quetoo.cfg") — an environment issue in the build container (no game data installed), unrelated to this change.
  • In-game smoke test against the live stats API (giblets.quetoo.org), headless under Xvfb/llvmpipe: client reaches the main menu with stats placeholders immediately, the GUID hash arrives asynchronously and the Stats tab populates, the Leaderboard tab loads live rows, sort-column clicks refetch and reorder without any UI stall, and selectOwnRow highlights the local player after the async reload. No warnings or errors in the console log.

Replace blocking HTTP calls in menu code paths with asynchronous
requests so the client no longer freezes (or shows a black screen at
launch) while waiting on the stats API:

- Add Net_HttpGetInstanceAsync and Net_HttpGetInstancesAsync, async
  counterparts to the JSON instance helpers, and expose them through
  the cgame import.
- Fetch the GUID hash asynchronously at startup; the result is applied
  on the main thread via a NOTIFICATION_GUID_HASHED MVC event.
- Fetch the leaderboard asynchronously; completed results are staged
  and applied in respondToEvent on NOTIFICATION_LEADERBOARD_FETCHED.
- Fetch player stats asynchronously; completed responses are staged
  and applied in respondToEvent on NOTIFICATION_STATS_FETCHED. Stats
  also refresh when the GUID hash arrives.
- Generation counters discard stale responses when a newer fetch has
  been issued; completion callbacks never touch UI state directly.
- Add check_http unit tests covering both new async JSON helpers.
@Eclipse1982 Eclipse1982 force-pushed the feature/async-ui-http branch from c84a48e to ef9d838 Compare June 12, 2026 23:05
@jdolan

jdolan commented Jun 13, 2026

Copy link
Copy Markdown
Owner

Fantastic! Thank you. I'm working on some improvements to the JSON deserialization code here first. I'll commit that and up-merge into your branch and get this over the finish line. This is a big win for user experience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use async HTTP requests for UI / stats where possible.

2 participants