How to make Nginx wait for a thread pool task

倾然丶 夕夏残阳落幕 提交于 2021-01-29 06:43:34

问题


I am writing a module that will handle the my http request. For this, I added a location content handler (or location directive handler) in my module. My content handler interfaces with a library which is not asynchronous. So within handler, I queue up a task to nginx thread pool. I also added a thread completion handler.

The problem I am running into is that Nginx doesn't wait for my thread to finish. With in my location content handler, I queue up task and return NGX_DONE and Nginx finalizes my request while thread is running. I also tried hooking up this handler code in HTTP_CONTENT_PHASE handler instead of location content handler, but no luck so far yet.

How can I make Nginx wait for my thread to finish before finalizing the request in HTTP_CONTENT_PHASE?


回答1:


I have finally found the solution. Here is some relevant snippet of code.

Queuing a task to thread from http request handler ( or location directive handler)

typedef struct {

    ngx_http_request_t  *pHttpRequest;

} ngx_thread_ctx;


    static ngx_int_t ngx_http_rdm_agent_handler(ngx_http_request_t *r)
    {
        ngx_thread_task_t    *task;
        ngx_thread_ctx *thread_ctx; // Thread context is my struct                                         
                                   // that has pointer to nginx_request_t struct
        ..........
        ..........  
        thread_ctx = (ngx_thread_ctx*)(task->ctx);
        thread_ctx->pHttpRequest = r;

        task->handler = my_thread_callback;
        task->event.handler = my_thread_completion;
        task->event.data = thread_ctx;

        //*** This is the key part. Increment this so nginx
        //*** won't finalize request (r)
        r->main->blocked++;

        // loc_cf -> location config struct where I added thread pool during 
        // configuration phase
        if (ngx_thread_task_post(loc_cf->pThreadPool, task) != NGX_OK) {
            r->main->blocked--;
            return NGX_ERROR;
        }

        return NGX_DONE;
    }

Completion handler of your thread

static void my_thread_completion(ngx_event_t *ev) 
{

    ngx_thread_ctx *ctx = (ngx_thread_ctx*)ev->data;    

    ctx->pHttpRequest->main->blocked--;

    ngx_http_finalize_request(ctx->pHttpRequest, NGX_DONE);
}


来源:https://stackoverflow.com/questions/55908530/how-to-make-nginx-wait-for-a-thread-pool-task

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!