What is the purpose of using httpd_queue_work?

wuyuanyi
Posts: 28
Joined: Wed Mar 09, 2022 11:54 am

What is the purpose of using httpd_queue_work?

Postby wuyuanyi » Sat Jan 07, 2023 12:44 pm

Hi, I am looking at the http server component and found this function: httpd_queue_work. After tracing the source code, I found that It merely ask the http server thread to invoke the work callback immediately. The callback is not called in a standalone thread. I wonder what is the purpose of using this function? How does it achieve asynchronous request handling? From my understanding, either in the request callback or the work callback, I should not invoke any blocking function because it will block the whole server thread and make it unable to respond to any other requests. Then why and when should I use httpd_queue_work?
Thanks

wuyuanyi
Posts: 28
Joined: Wed Mar 09, 2022 11:54 am

Re: What is the purpose of using httpd_queue_work?

Postby wuyuanyi » Sat Jan 07, 2023 2:49 pm

I succeed implementing the asynchronous response using the following code
Note the commented code, where I assumed that httpd_queue_work is used to delegate the http communication to the http server thread. However, without using httpd_queue_work it works just fine. This makes me wonder more when httpd_queue_work should be used.

Code: Select all

  
  void on_request_control(httpd_req_t* req) {
    auto fd = httpd_req_to_sockfd(req);
    auto hd = req->handle;
    std::thread t([=]() {
      vTaskDelay(pdMS_TO_TICKS(1000));
      const char* resp = "Hello after 1000 milliseconds!";
      httpd_socket_send_common_header(hd, fd, "text/plain", strlen(resp));
      httpd_socket_header_finishes(hd, fd);
      httpd_socket_send(hd, fd, resp, strlen(resp), 0);
//      auto args = new WorkArgs{hd, fd};
//      httpd_queue_work(
//          hd,
//          [](void* arg) {
//            auto args = (WorkArgs*)arg;
//            auto& hd = args->hd;
//            auto& fd = args->fd;
//
//            const char* resp = "Hello after 1000 milliseconds!";
//            httpd_socket_send_common_header(hd, fd, "text/plain", strlen(resp));
//            httpd_socket_header_finishes(hd, fd);
//            httpd_socket_send(hd, fd, resp, strlen(resp), 0);
//            delete args;
//          },
//          args);

    });
    t.detach();
  }
  

greycon
Posts: 22
Joined: Fri Nov 03, 2023 9:59 pm

Re: What is the purpose of using httpd_queue_work?

Postby greycon » Fri Nov 03, 2023 10:55 pm

wuyuanyi wrote:
Sat Jan 07, 2023 2:49 pm
I succeed implementing the asynchronous response using the following code
Note the commented code, where I assumed that httpd_queue_work is used to delegate the http communication to the http server thread. However, without using httpd_queue_work it works just fine. This makes me wonder more when httpd_queue_work should be used.

Code: Select all

  
  void on_request_control(httpd_req_t* req) {
    auto fd = httpd_req_to_sockfd(req);
    auto hd = req->handle;
    std::thread t([=]() {
      vTaskDelay(pdMS_TO_TICKS(1000));
      const char* resp = "Hello after 1000 milliseconds!";
      httpd_socket_send_common_header(hd, fd, "text/plain", strlen(resp));
      httpd_socket_header_finishes(hd, fd);
      httpd_socket_send(hd, fd, resp, strlen(resp), 0);
//      auto args = new WorkArgs{hd, fd};
//      httpd_queue_work(
//          hd,
//          [](void* arg) {
//            auto args = (WorkArgs*)arg;
//            auto& hd = args->hd;
//            auto& fd = args->fd;
//
//            const char* resp = "Hello after 1000 milliseconds!";
//            httpd_socket_send_common_header(hd, fd, "text/plain", strlen(resp));
//            httpd_socket_header_finishes(hd, fd);
//            httpd_socket_send(hd, fd, resp, strlen(resp), 0);
//            delete args;
//          },
//          args);

    });
    t.detach();
  }
 
Hello. I'm looking into async request handling on the ESP32 myself at the moment. So, using the above method are you happy you can have HTTP request "Worker threads" ? Do you happen to know if std:Thread::detach will allocate threads to the second core, if it happens to be free?
Thanks,Con

wuyuanyi
Posts: 28
Joined: Wed Mar 09, 2022 11:54 am

Re: What is the purpose of using httpd_queue_work?

Postby wuyuanyi » Wed Dec 06, 2023 7:46 am

greycon wrote:
Fri Nov 03, 2023 10:55 pm
wuyuanyi wrote:
Sat Jan 07, 2023 2:49 pm
I succeed implementing the asynchronous response using the following code
Note the commented code, where I assumed that httpd_queue_work is used to delegate the http communication to the http server thread. However, without using httpd_queue_work it works just fine. This makes me wonder more when httpd_queue_work should be used.

Code: Select all

  
  void on_request_control(httpd_req_t* req) {
    auto fd = httpd_req_to_sockfd(req);
    auto hd = req->handle;
    std::thread t([=]() {
      vTaskDelay(pdMS_TO_TICKS(1000));
      const char* resp = "Hello after 1000 milliseconds!";
      httpd_socket_send_common_header(hd, fd, "text/plain", strlen(resp));
      httpd_socket_header_finishes(hd, fd);
      httpd_socket_send(hd, fd, resp, strlen(resp), 0);
//      auto args = new WorkArgs{hd, fd};
//      httpd_queue_work(
//          hd,
//          [](void* arg) {
//            auto args = (WorkArgs*)arg;
//            auto& hd = args->hd;
//            auto& fd = args->fd;
//
//            const char* resp = "Hello after 1000 milliseconds!";
//            httpd_socket_send_common_header(hd, fd, "text/plain", strlen(resp));
//            httpd_socket_header_finishes(hd, fd);
//            httpd_socket_send(hd, fd, resp, strlen(resp), 0);
//            delete args;
//          },
//          args);

    });
    t.detach();
  }
Hello. I'm looking into async request handling on the ESP32 myself at the moment. So, using the above method are you happy you can have HTTP request "Worker threads" ? Do you happen to know if std:Thread::detach will allocate threads to the second core, if it happens to be free?
Thanks,Con
The thread should be pinned to a core if you want, using esp_pthread_cfg_set.

MicroController
Posts: 1552
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: What is the purpose of using httpd_queue_work?

Postby MicroController » Mon Dec 11, 2023 12:20 pm

I wonder what is the purpose of using this function? How does it achieve asynchronous request handling?
As you noted, httpd_queue_work(...) does not achieve asynchronous request handling. But it can (and probably should) be used in asynchrous handling of protocols.
You may have noticed that you can associate a custom 'session context' with an HTTP connection. This is extremely useful for handling protocols asynchronously, i.e. outside of a request handler.
The HTTPD will 'destroy' that session context (by calling the httpd_free_ctx_fn_t) when the associated 'session', i.e. connection, ends.
By enqueueing protocol handling with the HTTPD task the handling code becomes intrinsically synchronized with the HTTPD and thus it is guaranteed that HTTPD will not destroy your session context concurrently while your protocol handling is actively using it. I.e., when and while your httpd_work_fn_t runs, all your session objects are either valid or invalid/destroyed, but none can change from valid to destroyed mid-flight.

Who is online

Users browsing this forum: No registered users and 341 guests