Skip to content

Add minimum interval between consecutive HTTP requests#4

Open
amasolov wants to merge 1 commit into
glenndehaan:masterfrom
amasolov:add-request-interval
Open

Add minimum interval between consecutive HTTP requests#4
amasolov wants to merge 1 commit into
glenndehaan:masterfrom
amasolov:add-request-interval

Conversation

@amasolov

@amasolov amasolov commented May 24, 2026

Copy link
Copy Markdown

Summary

HDFury devices run an embedded web server with limited resources (similar to ESP32-class devices). When the Home Assistant integration polls for data every 60 seconds, it fires 4 HTTP GET requests in rapid succession (brdinfo.ssi, infopage.ssi, confpage.ssi, cecpage.ssi). Over time, this rapid-fire pattern can exhaust available sockets on the device's embedded HTTP server, causing it to become unresponsive and eventually crash (requiring a power cycle to recover).

This is the same class of issue seen in ESP-IDF based web servers (e.g. esphome/esphome#12481) where rapid polling without request spacing leads to httpd_accept_conn: error in accept (23).

Changes

  • Add _request_interval (default 1 second) to the HDFuryAPI class that enforces a minimum delay between any two consecutive HTTP requests
  • The interval is applied inside _request() so it covers all read and write operations uniformly
  • The existing _debounce_delay (which only gates reads after writes) is preserved unchanged
  • _last_request_time is updated even on errors, so the interval is still respected when the device is struggling
  • Added tests for the new interval behavior (all 70 tests pass, 100% coverage maintained)

Impact

  • Each polling cycle now takes ~4 seconds instead of <1 second (4 requests × 1s interval)
  • This is well within the 60-second polling window and has no user-visible impact
  • Significantly reduces the risk of socket exhaustion on the device firmware

Testing

  • All existing tests pass unchanged
  • Three new tests verify the interval behavior:
    • test_request_interval_spaces_consecutive_requests — confirms sleep when called too fast
    • test_request_interval_no_sleep_when_enough_time_elapsed — confirms no unnecessary delay
    • test_request_updates_last_request_time — confirms timestamp tracking

@glenndehaan

Copy link
Copy Markdown
Owner

Hi @amasolov,

Thank you for the contribution. I would suggest we utilize the debounce globally during a request and not creating a new function that now does the same thing as the debounce. Since right now both the old debounce and new request internal both keep track of requests delays on commands (since commands utilize the same _request function). So for me I would suggest we keep the debounce but utilize it in the way you proposed in this PR.

Kind regards,
Glenn de haan

Move the existing debounce mechanism into _request() so it applies
uniformly to all HTTP requests (reads and writes). Previously the
debounce only gated read requests that followed a write command.

Now every request waits at least _debounce_delay seconds since the
previous request completed, giving the device's embedded web server
time to recover between operations and preventing socket exhaustion
under sustained polling.

Changes:
- _wait_for_debounce() now tracks _last_request_time (all requests)
  instead of only command times
- Debounce is enforced inside _request(), removing per-method calls
- _send_command() no longer separately tracks command time
- _last_request_time is updated on errors so the delay is respected
  when the device is struggling
@amasolov amasolov force-pushed the add-request-interval branch from be01d05 to 5c80d5a Compare May 24, 2026 22:53
@amasolov

Copy link
Copy Markdown
Author

Thanks for the feedback! I've reworked this to use the existing _debounce_delay globally as you suggested.

Changes in this update:

  • Removed the separate _request_interval mechanism entirely
  • Moved _wait_for_debounce() into _request() so it applies uniformly to all HTTP requests (reads and writes)
  • Renamed tracking from _last_command_time to _last_request_time since we now track all requests
  • Removed the per-method _wait_for_debounce() calls from get_board(), get_info(), get_config()
  • _send_command() no longer separately tracks time (handled by _request())

The result is one clean mechanism: every request waits at least _debounce_delay seconds since the last request completed, regardless of whether it's a read or write. This keeps the device's embedded web server from being overwhelmed during polling cycles.

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

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants