ESP8266Scheduler icon indicating copy to clipboard operation
ESP8266Scheduler copied to clipboard

Any online request causing delay on the main loop

Open PawelSzymanski89 opened this issue 5 years ago • 9 comments

I have one task with simple request to REST api and if i'll start in main esp loop is waiting for response...

class ApiRequest : public Task {
  public:
    void loop() {
      Serial.println("ApiRequest");
      if (WiFi.status() == WL_CONNECTED) {
        client.get("/basementData");
        int statusCode = client.responseStatusCode();
        String resBody = client.responseBody();
        //        Serial.println("-------------------------");
        //        Serial.println(resBody);
        if (statusCode = 200) {
          JsonObject root = doc.as<JsonObject>();
          auto error = deserializeJson(doc, resBody);
          if (!error) {
            //            double stoveTemp = root["stoveTemperature"];
            stoveTemperature = (int)root["stoveTemperature"];
            waterTemperature = (int)root["waterTemperature"];
            timeMills = root["timeStamp"];
          }
        }
      }
    }
} api_task;

PawelSzymanski89 avatar Jan 04 '20 22:01 PawelSzymanski89

What is the issue exactly?

nrwiersma avatar Jan 05 '20 04:01 nrwiersma

client.get will wait ~~using the global Delay~~ until the response is received and call the global yield, this blocks the tasks.

The only ways around this I can think of are:

  • Implement the get request yourself so you can call the task-specific delay function instead code
  • Expose Scheduler.current->delay globally ~~and wrap the include"HTTPclient" around #define and #undefine to change the calls to global delay and yield to Scheduler.current->delay. (hacky but sounds fun)~~ (didn't get it to work)

dbuezas avatar Feb 03 '21 17:02 dbuezas

I found a way to make this work:

  1. expose the yield function of the current Task (e.g SchedulerClass::yield())
  2. Make a new class that inherits from HTTPSClient
class HTTPSClientScheduled : public HTTPSClient {
  int available() override {
    SchedulerClass::yield();
    return HTTPSClient::available();
  }
};
  1. instantiate a client from HTTPSClientScheduled instead.

This works because GET makes extensive use of readStringUntil, which in term calls available, which just happens to be overridable. I'm using it with HTTPSRedirect


@nrwiersma would you consider a PR that exposes yield and delay in that way inside the Scheduler class?

dbuezas avatar Feb 06 '21 18:02 dbuezas

@dbuezas In light of #20 it seems unlikely.

nrwiersma avatar Feb 07 '21 05:02 nrwiersma

I think it can be done ~(I first have to understand the run groups thing), I'll make a separate PR after #20~ gave up on making it work with run groups. For this functionality (w/o run groups), there's a fork

dbuezas avatar Feb 07 '21 11:02 dbuezas