Система акторов Akka.NET в ASP.NET

Я создал службу с RESTful API в ASP.NET, размещенную в IIS. Внутри этого сервиса я хотел бы создать систему акторов с помощью Akka.NET.

При создании системы актеров:

var actorSystem = ActorSystem.Create("myActorSystem");

Выдается следующее исключение:

Первое случайное исключение типа «System.InvalidOperationException» произошло в System.Web.dll. Дополнительная информация: асинхронная операция не может быть запущена в это время. Асинхронные операции могут запускаться только в асинхронном обработчике или модуле или во время определенных событий в жизненном цикле страницы. Если это исключение произошло при выполнении страницы, убедитесь, что страница помечена как ‹% @ Page Async =" true "%>. Это исключение также может указывать на попытку вызвать метод «async void», который обычно не поддерживается при обработке запросов ASP.NET. Вместо этого асинхронный метод должен вернуть задачу, а вызывающий должен ее дождаться.

Система акторов по своей сути является параллельной системой с асинхронными сообщениями, которыми обмениваются акторы. Как объяснено здесь, эта система акторов не сможет выжить, если IIS отключит домен приложения, что, вероятно, является причиной возникновения вышеупомянутого исключения.

В этой статье объясняется, как запускать фоновые задачи в ASP.NET. Однако я не понимаю, как я могу использовать это для своей системы акторов, поскольку я не контролирую жизненный цикл фоновых задач, которые могут быть созданы Akka.NET.

Есть ли способ заставить эту работу работать, или мне следует отказаться от идеи наличия системы акторов в приложении ASP.NET?

РЕДАКТИРОВАТЬ: Я также видел вопрос в Stackoverflow о реализации службы REST используя Akka. Приветствуются любые советы по решению, аналогичному Spray toolkit, но работающему на Akka.NET.


person Odsh    schedule 24.12.2014    source источник
comment
Актерская модель звучит круто. Но так ли оно вам нужно?   -  person odinserj    schedule 24.12.2014
comment
Я пробую это как доказательство концепции, мне это абсолютно не нужно. Можно сделать вывод, что это будет слишком сложно.   -  person Odsh    schedule 24.12.2014


Ответы (2)


Сохраните ActorSystem как общее свойство в каком-то контейнере статического класса - таким образом вы можете получить к нему доступ из остальной части вашего приложения. Инициализация / удаление системы акторов может быть произведена следующими способами:

  • Global.asax - используйте ActorSystem.Create(...) внутри Global.asax Application_Start и удалите его с помощью system.Shutdown() на Application_End.
  • OWIN - создайте систему акторов в методе Startup.Configuration OWIN и выключите ее, привязав к событию host.OnAppDisposing (ссылка с инструкциями).

Помните, что IIS запустит ваше веб-приложение только после первого запроса и автоматически отключит его через некоторое время, когда оно простаивает. Поэтому убедитесь, что ваш сценарий развертывания будет проверять связь с приложением после публикации и установить тайм-аут простоя (link) достаточно долго, если вы хотите, чтобы ваша система акторов Akka работала непрерывно.

Второй вариант

Отделите логику системы акторов и разверните ее, например, как службу Windows (или демона Linux). Включите для него Akka.Remoting и создайте прокси-клиента, который будет перенаправлять все длительные конфиденциальные задачи приложения во внешнюю службу. Подобное решение часто используется для таких вещей, как планировщики или шины событий, когда логика вашего приложения должна работать непрерывно.

person Bartosz Sypytkowski    schedule 31.12.2014
comment
Спасибо за ответ, Хорусиат. Думаю, мне нужно будет выбрать второй вариант. Первый из них трудно применить в моем случае, поскольку система акторов потенциально может выполнять очень длинные или непрерывные задачи. - person Odsh; 06.01.2015

Я использовал Akka.NET и Akka.Remote внутри приложений ASP.NET MVC, которые выполняют до 1000 запросов в секунду на EC2, поэтому я поделюсь некоторыми советами и приемами, которые я использовал для его успешного запуска и работы. Была версия прототипа, в которой даже использовался Akka.Cluster, но в итоге эта версия не была отправлена.

  • Лучшее место для звонка ActorSystem.Create - внутри Global.asax Application_Start().
  • Зацепитесь за статическую ссылку на объект ActorSystem внутри самого Global.asax, используя статическое поле или свойство. Помогает гарантировать, что ActorSystem не будет собирать мусор в долго работающих приложениях.
  • Создайте отдельный статический вспомогательный класс для инициализации любых субъектов верхнего уровня, необходимых вашим приложениям, т. Е. Субъектов на вершине иерархии /user/. Этот класс также должен предоставлять пути к участникам, которые ваши контроллеры ASP.MVC и методы действий могут использовать для операций Tell и Ask.

Создание ActorSystem - довольно дорогостоящая операция, потому что сразу запускается множество вещей системного уровня. Определенно лучше сделать это один раз при запуске приложения, а затем просто кэшировать результат внутри класса Application.

Создание отдельных экземпляров акторов обходится недорого - вы сможете без проблем сделать это внутри методов действий ASP.NET MVC. Если вы снова видите эту ошибку, сообщите нам, в какой части процесса обработки запроса возникла эта ошибка и с какой версией ASP.NET.

person Aaronontheweb    schedule 25.12.2014
comment
Спасибо за ответ Аарон. Как объяснено на этот сайт, ASP.NET может отключить ваш домен приложений в любое время, тем самым прервав любое фоновое выполнение в вашем приложении. Что случится с вашей актерской системой, когда это произойдет? - person Odsh; 29.12.2014
comment
Во всех этих сценариях Akka.NET работает внутри домена приложений ASP.NET, поэтому в случае любого из сценариев, описанных Haack, ваше веб-приложение будет переработано вместе с вашей системой акторов (редактирование web.config, повторный цикл процесса IIS, и т. д.). В зависимости от среды хостинга вы можете управлять всем этим с помощью настроек IIS и machine.config. Тем не менее, ActorSystem по-прежнему будет активна в то же время, что и ваше веб-приложение - нет ничего, что могло бы пройти и убить вашу ActorSystem, но оставит приложение ASP.NET нетронутым, следуя тому, что я сказал выше. - person Aaronontheweb; 30.12.2014
comment
система акторов будет активна одновременно с моим веб-приложением, да. Чего я бы хотел избежать, так это того, чтобы эта система акторов останавливалась без предупреждения при перезапуске с еще активными участниками и непустыми очередями сообщений. - person Odsh; 06.01.2015