LINUX.ORG.RU

Asyncio обработка задач различного типа корутинами.

 , ,


0

1

Добрый день. Возникла необходимость сделать следующее.

На старте мы запускаем, допустим, с десяток корутин. Их задача - брать из очереди задачи и выполнять их. Если же задачи нету, то тогда необходимо просто спать и отдавать управление в event loop. Но к самим задачам, которые мы добавляем, должен так же прибавлятся дополнительный 'тег'. Грубо говоря, метка. При запросе задачи из очереди, мы можем в параметрах передать тег или список тегов, по которым задачи возвращаться не должны. Как такое реализовать? Писать свою очередь? Как вариант - брать задачу из очереди, и если она не нужного нам типа, то тогда просто возвращать ее обратно в очередь. Но мне кажется, что это просто хак и будет работать он очень медленно, т.к перебирать задачи мы можем долго таким образом + гонять их туда-сюда. Второй вариант, приходящий в голову - использовать какие-либо примитивы синхронизации и создавать на каждый тип задачи отдельную очередь, уведомляя о ней корутины. Если сформулировать задачу более формально, то необходимо следующее - мы создаем кучу одинаковых задач, их может быть =< количество корутин. Все должны быть выполнены, но каждая корутина не должна взять больше одной задачи. Подвох в том, что в процессе получения задач из очереди, мы можем добавить еще туда одинаковых задач, но уже «другого» типа.

На старте мы запускаем, допустим, с десяток корутин. Их задача - брать из очереди задачи и выполнять их. Если же задачи нету, то тогда необходимо просто спать и отдавать управление в event loop.

Все - закончили. Это так не работает. Есть один цикл while где ты берешь задачи. Потом делаешь

task = loop.create_task(
         self.bg_task(args)
                    )

А вообще ты зачем не хочешь использовать нормальный MQ. ZeroMQ, RabbitMQ, Kafka...

dem ()

На старте мы запускаем, допустим, с десяток корутин.

Зачем? Достаточно одной, которая разбирает очередь и запускает соответствующие обработчики.

vvn_black ★★★★ ()
Ответ на: комментарий от WitcherGeralt

Не совсем. У нас есть несколько HTTP клиентов, которые должны держать keep-alive соединения, и соотвественно, принимая задачи, обрабатывать. Естественно, что они буду отдавать управление в loop и делать wait, пока не придет задача или же данные из соединения. Не знаю, у меня не такой большой опыт с асинхронщиной. Возможно я понимаю что-то не так, как стоит делать это.

crarkie ()

у вас каша в голове, такое никто не делает и смысла в этом нет. делайте каждую задачу корутиной и этими корутинами(задачами) уже и жонглируйте. поизучайте как устроен ГОУ ланг, там корутины самая основная идея всего языка

anonymous ()
Ответ на: комментарий от crarkie

Не будут они делать wait. У тебя 1 эвентлуп который будет слушать http. На каждый запрос ты будешь порождать await и это будет корутина. Тебе тут вообще ничего не надо делать. Если задача долгая то делаешь таск. Статус его кладешь куданибудь, и отправляешь ее ID клиент пусть попросит через секунду. Но если кипалив, то ничего не надо в таски просто await и как корутина ответит, та к и отправишь (ну там еще могут таймауты и вообще это хрень...)

dem ()
Ответ на: комментарий от crarkie

Создаёшь эти 10 корутин, кладёшь в луп с loop.ensure_future, внутри корутины авейтишь свои иветы. Естественно, получение ивентов должно быть основано на том же самом принципе. Смотри в сторону aiohttp.

WitcherGeralt ★★ ()
Последнее исправление: WitcherGeralt (всего исправлений: 1)
Ответ на: комментарий от menangen

Node.js

Я бы сказал, куда идти с такими предложениями, но надеюсь, вы сами найдете дорогу. Не надо вставлять свое УГ, когда просят рецепты для асинхронщины на Python.

crarkie ()
Ответ на: комментарий от menangen

С таких, что я не хочу лезть в дебри вашего JS. У меня нет настолько большой нагрузки, чтобы она камнем упиралась в производительность. И пишется на Python намного проще и быстрее. JS мне не нравится как язык. Ссори

crarkie ()
Ответ на: комментарий от menangen

Ты так и не понял, о чем я. Как язык, мне Python нравится намного больше, нежели JS. Дело не в том, как эта асинхронщина пишется там. Да и с приходом asyncio, пишется она тут ненамного сложнее, чем на вашем NodeJS. Разве что входной порог выше. NodeJS изначально делали для фронтенд разрабов, чтобы не переучивать их на новый язык. В свое время это сыграло на руку, да. И то, что в нем была асинхронщина из коробки - тоже да. Но сейчас он уже отходит на второй план. Потому как асинхронщину умеют многие. Go - так вообще может утилизировать все ядра для этого. В отличие от однопоточной ноды. Но Go как язык подходит идеально не для всех задач, я пробовал. Сложную бизнес логику писать на нем тяжеловато. Микросервисы - да, пожалуйста, все выходит красиво и просто.

crarkie ()