Dotnetcore http поток Асинхронное ожидание головоломки - PullRequest
0 голосов
/ 07 января 2019

в базовом http-приложении dotnet у нас есть вызов, который выполняет работу, выполняет несколько вызовов http для вспомогательных служб и возвращает. Это было все асинхронное ожидание. Это означало, что вызов ожидал, пока службы поддержки выполнят свою работу, прежде чем ответить на звонок клиенту. это вызывало вызов тайм-аута.

Решение, которое было представлено, состояло в том, чтобы полностью удалить асинхронное ожидание до минимума, после чего мы могли бы просто обернуть вызовы http (все еще методы асинхронной задачи) в теги прагмы, которые подавляют предупреждение / ошибку компилятора.

Это заставляет меня нервничать, потому что вы не гарантируете, что окончательные (или любые) запросы http будут выполнены до того, как вызывающий поток вернется, и асинхронные машины, связанные с этим потоком, будут очищены.

Я что-то упустил? это одна из тех странных, но полезных ситуаций? или было бы более уместно выделить потоки для обработки этих вызовов http?

1 Ответ

0 голосов
/ 09 февраля 2019

Вы говорите о Огонь и забудь , и ты прав, что будешь волноваться. Есть несколько проблем с огнем и забыть. Это потому, что «забыть» означает «забыть», и это почти всегда неправильное решение, чтобы ваше приложение просто забыло о чем-то.

Если есть исключение, вызывающее один из этих внутренних HTTP-запросов, это исключение будет проигнорировано, если у вас нет специальной логики, обрабатывающей эту ситуацию. И помните, больше нет внешнего запроса, поэтому возврат ошибки невозможен (возврату некуда). Таким образом, у вас есть возможность молча проглотить ошибки. Это должно заставить вас нервничать.

Кроме того, у вас есть проблема с тем, чтобы не сообщать ASP.NET, что у вас есть постоянная фоновая работа. Возвращаясь рано, вы говорите ASP.NET отправить ответ, и все в порядке, хотя на самом деле работа не завершена, и вы не представляете, когда она будет выполнена или даже будет ли она успешной. Дело в том, что ничто из вышеперечисленного вашего кода (включая ASP.NET, IIS / Kestrel, прокси, балансировщики нагрузки) не имеет ни малейшего представления, что ваш код все еще работает - в конце концов, ваш код просто сказал всем этим вещам, что он сделано обработка этого запроса. Будет ли ASP.NET отвечать на запрос на выключение? Конечно! Может ли IIS периодически повторять пул приложений? Конечно! Может ли ваш прокси вывести этот узел из ротации при непрерывном обновлении? Конечно! Будет ли ваш балансировщик нагрузки отправлять больше работы, поскольку он ничего не делает? Конечно! Насколько известно любой из этих систем, ваше приложение на самом деле не обрабатывает этот запрос, и это может вызвать проблемы, например, ваша работа «запусти и забудь» внезапно исчезнет - опять же, без каких-либо исключений, журналов или чего-либо еще. Это должно заставить вас нервничать.

Я бы сказал, что лучший подход - это исправить нисходящие вызовы, если это возможно. Также обратите внимание на асинхронный параллелизм, например, начиная несколько вызовов, а затем await Task.WhenAll. Если этих подходов недостаточно, я бы порекомендовал правильную распределенную архитектуру: пусть API записывает в постоянную очередь, а фоновая работа выполняется отдельным приложением, которое обрабатывает эту очередь.

...