Websocket-сервер для геолокации на asyncio
Вебсокеты нужны там, где идет взаимодействие с пользователем в режиме реального времени. С их помощью клиент может послать запрос к серверу, как в обычном HTTP. Но самое интересное, что используя вебсокеты, сервер тоже может послать данные клиенту, не дожидаясь от него HTTP-запроса.
В этой статье вы узнаете, как создать веб-сервис, который позволяет делиться своим местоположением и отслеживать местоположение всех остальных подключенных к нему людей на карте мира в режиме реального времени:
https://habr.com/ru/company/kts/blog/659341/
#веб #websocket #asyncio
Вебсокеты нужны там, где идет взаимодействие с пользователем в режиме реального времени. С их помощью клиент может послать запрос к серверу, как в обычном HTTP. Но самое интересное, что используя вебсокеты, сервер тоже может послать данные клиенту, не дожидаясь от него HTTP-запроса.
В этой статье вы узнаете, как создать веб-сервис, который позволяет делиться своим местоположением и отслеживать местоположение всех остальных подключенных к нему людей на карте мира в режиме реального времени:
https://habr.com/ru/company/kts/blog/659341/
#веб #websocket #asyncio
👍12🔥3
asyncio для сетевых инженеров
Исчерпывающий гайд, с помощью которого вы узнаете, в чём разница между параллельными процессами, потоками и асинхронным программированием.
Руководство под авторством Натальи Самойленко разделено на несколько частей:
— основы работы с сопрограммами;
— асинхронные модули;
— создание классов в asyncio;
— использование модуля asyncio;
— работа с циклом событий.
Документация также дополняется блоком заданий и примеров кода.
#asyncio
Исчерпывающий гайд, с помощью которого вы узнаете, в чём разница между параллельными процессами, потоками и асинхронным программированием.
Руководство под авторством Натальи Самойленко разделено на несколько частей:
— основы работы с сопрограммами;
— асинхронные модули;
— создание классов в asyncio;
— использование модуля asyncio;
— работа с циклом событий.
Документация также дополняется блоком заданий и примеров кода.
#asyncio
❤7🔥4👍3
Как дождаться обработки очереди asyncio
Пустая очередь ещё не означает, что работа закончена: потребитель мог забрать элемент и продолжать его обработку. asyncio.Queue.join() ориентируется на число неподтверждённых задач, а не на количество элементов внутри очереди.
В схеме producer/consumer каждому успешному get() соответствует один task_done(). Подтверждение ставят после обработки, обычно в finally. Если подтверждать и неудачные задачи, join означает завершение учёта, а успех и повторную обработку нужно отслеживать отдельно.
maxsize ограничивает накопление: await put() ждёт, пока появится место. Для остановки потребителя можно отправить отдельный маркер, который тоже требует task_done(). Сам join работников не останавливает — после него нужно дождаться завершения их задач.
#python #asyncio
Пустая очередь ещё не означает, что работа закончена: потребитель мог забрать элемент и продолжать его обработку. asyncio.Queue.join() ориентируется на число неподтверждённых задач, а не на количество элементов внутри очереди.
В схеме producer/consumer каждому успешному get() соответствует один task_done(). Подтверждение ставят после обработки, обычно в finally. Если подтверждать и неудачные задачи, join означает завершение учёта, а успех и повторную обработку нужно отслеживать отдельно.
maxsize ограничивает накопление: await put() ждёт, пока появится место. Для остановки потребителя можно отправить отдельный маркер, который тоже требует task_done(). Сам join работников не останавливает — после него нужно дождаться завершения их задач.
#python #asyncio
Как измерять время async-функции через декоратор
Обычная обёртка может вызвать async-функцию и получить объект корутины за микросекунды. Это ещё не время запроса: выполнение корутины начнётся позже, а исключение возникнет уже за пределами обёртки.
В разборе async-декораторов обёртка сама объявлена через async def. Она сохраняет время старта, выполняет return await fn(*args, **kwargs), а запись длительности помещает в finally.
Так измерение охватывает выполнение и очистку при ошибке или отмене. functools.wraps сохраняет метаданные и связь wrapped для интроспекции. Сам сборщик метрик тоже должен быть аккуратным: его ошибка в finally способна перекрыть исходное исключение, а блокирующий ввод-вывод задержит весь event loop.
#python #asyncio
Обычная обёртка может вызвать async-функцию и получить объект корутины за микросекунды. Это ещё не время запроса: выполнение корутины начнётся позже, а исключение возникнет уже за пределами обёртки.
В разборе async-декораторов обёртка сама объявлена через async def. Она сохраняет время старта, выполняет return await fn(*args, **kwargs), а запись длительности помещает в finally.
Так измерение охватывает выполнение и очистку при ошибке или отмене. functools.wraps сохраняет метаданные и связь wrapped для интроспекции. Сам сборщик метрик тоже должен быть аккуратным: его ошибка в finally способна перекрыть исходное исключение, а блокирующий ввод-вывод задержит весь event loop.
#python #asyncio
Почему копия контекста не делает словарь отдельным
contextvars помогает хранить request ID для задач, которые выполняются на одном потоке event loop. При обычном создании asyncio.Task контекст копируется, поэтому новая задача получает текущую привязку переменной.
Но копия контекста поверхностная. Если ContextVar содержит словарь, родитель и дочерняя задача могут видеть один объект. Изменение его содержимого будет общим; set с новым значением меняет привязку в текущем контексте.
Для метаданных запроса удобнее неизменяемые значения. После set сохраняйте токен и восстанавливайте предыдущую привязку через reset в finally. Дочерняя задача может сохранить захваченный контекст и после завершения запроса, поэтому долгоживущей фоновой работе передавайте только необходимые данные.
#python #asyncio
contextvars помогает хранить request ID для задач, которые выполняются на одном потоке event loop. При обычном создании asyncio.Task контекст копируется, поэтому новая задача получает текущую привязку переменной.
Но копия контекста поверхностная. Если ContextVar содержит словарь, родитель и дочерняя задача могут видеть один объект. Изменение его содержимого будет общим; set с новым значением меняет привязку в текущем контексте.
Для метаданных запроса удобнее неизменяемые значения. После set сохраняйте токен и восстанавливайте предыдущую привязку через reset в finally. Дочерняя задача может сохранить захваченный контекст и после завершения запроса, поэтому долгоживущей фоновой работе передавайте только необходимые данные.
#python #asyncio
Почему тайм-аут не всегда заканчивается ровно по часам
asyncio.TaskGroup владеет созданными в нём задачами и ждёт их завершения. Если одна падает с обычным исключением, группа запрашивает отмену остальных, дожидается очистки и собирает ошибки в ExceptionGroup.
В разборе отмены и тайм-аутов важна граница: cancel() отправляет запрос, а задача должна получить CancelledError и выполнить finally. Если она подавляет отмену или долго очищает ресурсы, завершение затянется.
wait_for() ждёт окончания отмены, поэтому фактическое время может превысить заданный timeout. Контекст asyncio.timeout() отменяет текущую задачу и преобразует свою отмену в TimeoutError снаружи блока. Для связанных операций помещайте TaskGroup внутрь timeout, чтобы дочерняя работа имела явного владельца.
#python #asyncio
asyncio.TaskGroup владеет созданными в нём задачами и ждёт их завершения. Если одна падает с обычным исключением, группа запрашивает отмену остальных, дожидается очистки и собирает ошибки в ExceptionGroup.
В разборе отмены и тайм-аутов важна граница: cancel() отправляет запрос, а задача должна получить CancelledError и выполнить finally. Если она подавляет отмену или долго очищает ресурсы, завершение затянется.
wait_for() ждёт окончания отмены, поэтому фактическое время может превысить заданный timeout. Контекст asyncio.timeout() отменяет текущую задачу и преобразует свою отмену в TimeoutError снаружи блока. Для связанных операций помещайте TaskGroup внутрь timeout, чтобы дочерняя работа имела явного владельца.
#python #asyncio