Skip to content

Eliminate gigantic blocking time inside ESP8266WiFiMulti::run #4888

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from

Conversation

braddr
Copy link

@braddr braddr commented Jul 4, 2018

I'm using an esp8266 + Arduino in a project and need to keep the loop latencies low (low 10's of ms). Using ESP8266WiFiMulti connections result in multi-second pauses due largely to the connection loop inside run().

This change (developed and tested against 2.4.1 but looks to apply to head of master cleanly):

  1. pulls a couple functions out of the long run(), and
  2. introduces a new state variable to track an in-progress connection attemp

This takes the latency down to only once hitting a wifimulti.run() latency > 10ms, and that at only 14ms.

@braddr
Copy link
Author

braddr commented Jul 4, 2018

For what it's worth, I'm still seeing a single 880+/- 5 ms latency that's occurring between loop() calls that I haven't identified the source of yet. It happens between the wifi.begin() and the completion of the connection. Between the 0->2 and 2->3 state transitions:

state: 0 -> 2 (b0)
892 - loop
state: 2 -> 3 (0)

@braddr
Copy link
Author

braddr commented Jul 4, 2018

The failing sub-build:

core/test_md5builder.cpp:65: FAILED:
REQUIRE( builder.toString() == "bc4a2006e9d7787ee15fe3d4ef9cdb46" )
with expansion:
1 == "bc4a2006e9d7787ee15fe3d4ef9cdb46"

Am I going blind or aren't those two strings the same, just like the require wants them to be?

@d-a-v
Copy link
Collaborator

d-a-v commented Jul 4, 2018

This CI bug is yet unsolved and happens from time to time. I retriggered.

@beegee-tokyo
Copy link

Like this!
I had problems with WiFiMulti blocking my system when the connection got lost. Your solution is much better.

Copy link
Contributor

@yoursunny yoursunny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BestNetwork type seems to be private to ESP8266WiFiMulti class. If so, it could be a nested class, so that it does not pollute global namespace.

BestNetwork() : Network({NULL, NULL}), NetworkDb(INT_MIN) {}
};

void ESP8266WiFiMulti::selectBest(BestNetwork& best, int8_t scanResult) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only external dependency of this function is on WiFi. It doesn't depend on any WiFiMulti method or member. Therefore, there is no point of having the function in the class as a method.
Please make it a static free-standing function in the .cpp.

@@ -58,6 +60,12 @@ class ESP8266WiFiMulti {

private:
WifiAPlist APlist;
unsigned long connect_timeout_ms;

void selectBest(BestNetwork& best, int8_t scanResult);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function should be removed from the class, see comment above.

@@ -47,6 +47,8 @@ struct WifiAPEntry {

typedef std::vector<WifiAPEntry> WifiAPlist;

struct BestNetwork;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If selectBest is removed from the class and made a static free standing function, there is no need to declare this here, because the definition in the .cpp is enough. Please remove.

unsigned long connect_timeout_ms;

void selectBest(BestNetwork& best, int8_t scanResult);
void handleConnectComplete(wl_status_t status);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a debug method, and there is also no need for it to be part of the class, or exported in the .h. Please remove and make the function a static free standing function in the .cpp.

@@ -38,8 +38,104 @@ bool ESP8266WiFiMulti::addAP(const char* ssid, const char *passphrase) {
return APlistAdd(ssid, passphrase);
}

void ESP8266WiFiMulti::handleConnectComplete(wl_status_t status) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function has no dependencies on other class members or methods, and is not public. Please make it a static free standing function.

(millis() > connect_timeout_ms))
{
handleConnectComplete(status);
connect_timeout_ms = 0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a constructor-inited member, yet it is cleared here. Will it never be used again? Is there a need to init it again?

wl_status_t ESP8266WiFiMulti::run(void) {

if (connect_timeout_ms != 0) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The timeout value is cleared above and never set again. Is that correct behavior?

@earlephilhower earlephilhower added merge-conflict PR has a merge conflict that needs manual correction waiting for feedback Waiting on additional info. If it's not received, the issue may be closed. labels Oct 1, 2019
@earlephilhower
Copy link
Collaborator

Thanks for your PR, but the core and libraries have changed enough that this PR now has a merge conflict.

Could you merge it manually with the latest core, so we can consider it for future releases?

@devyte
Copy link
Collaborator

devyte commented Oct 2, 2020

Closing in favor of #7619 , which should be equivalent.

@devyte devyte closed this Oct 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merge-conflict PR has a merge conflict that needs manual correction waiting for feedback Waiting on additional info. If it's not received, the issue may be closed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants