Как заставить Nginx ждать задачи пула потоков - PullRequest
0 голосов
/ 29 апреля 2019

Я пишу модуль, который будет обрабатывать мой http-запрос. Для этого я добавил обработчик содержимого местоположения (или обработчик директивы местоположения) в мой модуль. Мой обработчик контента взаимодействует с библиотекой, которая не является асинхронной. Итак, в обработчике я ставлю задачу в очередь потоков nginx. Я также добавил обработчик завершения потока.

Проблема, с которой я сталкиваюсь, заключается в том, что Nginx не ждет завершения моего потока. В моем обработчике содержимого местоположения я ставлю задачу в очередь и возвращаю NGX_DONE, и Nginx завершает мой запрос во время работы потока. Я также попытался подключить этот код обработчика в обработчике HTTP_CONTENT_PHASE вместо обработчика содержимого местоположения, но пока не повезло.

Как я могу заставить Nginx дождаться завершения потока, прежде чем завершить запрос в HTTP_CONTENT_PHASE?

1 Ответ

0 голосов
/ 02 мая 2019

Я наконец нашел решение.Вот некоторый соответствующий фрагмент кода.

Постановка задачи в поток из обработчика запросов http (или обработчика директивы расположения)

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;
    }

Обработчик завершенияваша тема

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);
}
...