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
What is the purpose of using httpd_queue_work?
Re: What is the purpose of using httpd_queue_work?
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.
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();
}
Re: What is the purpose of using httpd_queue_work?
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?wuyuanyi wrote: ↑Sat Jan 07, 2023 2:49 pmI 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(); }
Thanks,Con
Re: What is the purpose of using httpd_queue_work?
The thread should be pinned to a core if you want, using esp_pthread_cfg_set.greycon wrote: ↑Fri Nov 03, 2023 10:55 pmHello. 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?wuyuanyi wrote: ↑Sat Jan 07, 2023 2:49 pmI 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(); }
Thanks,Con
-
- Posts: 1694
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: What is the purpose of using httpd_queue_work?
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.I wonder what is the purpose of using this function? How does it achieve asynchronous request handling?
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 150 guests