Можете ли вы иметь вложенные асинхронные контексты? - PullRequest
0 голосов
/ 16 января 2019

Итак, если AsyncContext::complete закрывает ответ, и мне нужно записать ответ в асинхронном контексте, как мне реализовать многошаговый ответ, в котором некоторый шаги блокируются с неблокирующими секциями между ними?

1 Ответ

0 голосов
/ 16 января 2019

Вы, похоже, действуете из-за неправильного понимания природы AsyncContext и семантики ServletRequest::startAsync. Этот метод (повторно) инициализирует AsyncContext для запроса и связанного ответа, сначала создает его, если необходимо, и связывает его с парой запрос / ответ. Это переводит запрос в асинхронный режим , который по своей сути означает лишь то, что контейнер не будет считать обработку запроса завершенной, пока не будет вызван метод complete() из предоставленного контекста .

В частности, создание асинхронного контекста не создает потоков и не назначает связанный запрос другому потоку, а методы AsyncContext запускаются в вызывающем их потоке (хотя это и является технической особенностью для AsyncContext::start ). Контекст в первую очередь является объектом для любого асинхронного кода, который вы предоставляете для использования для взаимодействия с контейнером, что в противном случае он не смог бы сделать безопасно. Чтобы фактически выполнить обработку в каком-либо другом потоке, вам необходимо организовать существование этого потока и назначить ему работу. AsyncContext::start - это удобный способ сделать это, но не единственный.

Относительно конкретно

как мне реализовать многошаговый ответ, в котором некоторые шаги блокируются с неблокирующими секциями между ними?

, основной ответ - "как хочешь". AsyncContext не мешает и не помогает вам, потому что речь идет о связи с контейнером, а не о рабочем процессе. В частности, я не вижу необходимости или специального использования для вложенных AsyncContext с.

Я думаю, вы описываете конвейер обработки с определенной ограниченной параллелизацией. Вы можете реализовать это, скажем, запустив весь рабочий процесс - я полагаю, все «блокирующие» шаги в потоке, запущенном через AsyncContext::start, и перенесите другую работу в пул потоков, в каких бы единицах измерения ни было целесообразно. Имейте в виду, однако, что объекты запроса и ответа не являются потокобезопасными. В идеале основной поток извлекает все необходимые данные из запроса и выполняет все необходимые записи в ответ.

В качестве альтернативы, возможно, вы используете обычный поток обработки запросов для основного рабочего процесса, соответственно распределяете фрагменты работы в пул потоков и вообще пропускаете бит AsyncContext. Нет необходимости в абсолютном смысле использовать AsyncContext для выполнения асинхронных вычислений в веб-приложении - его назначение и модели обработки, для которых оно предназначено, являются гораздо более конкретными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...