Python has had async for 10 years – why isn't it more popular? 🔥 Горячее 💬 Длинная дискуссия
- Async в Python уже 10 лет, но до сих пор не стал мейнстримом.
- Причины:
- ошибки «забыл
await
», трудно отлаживать; - GIL приучил не думать о параллелизме;
- польза только при I/O-задачах, CPU-нагрузка не ускоряется;
- фреймворки не догнали: Django ORM всё ещё синхронен, Flask тоже.
- ошибки «забыл
- Классический кейс — HTTP-запросы: стартуем сотни корутин, ждём ответов, не блокируем интерпретатор.
- Но дисковый I/O, CPU-задачи и другие сценарии не так выигрывают.
- Вывод: чтобы новые фичи 3.14 (free-threading, sub-interpreters) не повторили судьбу async, нужно:
- чётко объяснять, какие задачи они решают;
- давать простые API и инструменты отладки;
- не ждать, пока экосистема «догонит», а сразу внедрять в популярные библиотеки.
Комментарии (234)
- Async в Python пришёл «слишком поздно»: к моменту появления asyncio большинство уже решали задачи I/O через forking, multiprocessing или сторонние библиотеки.
- «Цветные функции» и необходимость переписывать весь код ради async делают его «заразным» и несовместимым с существующими синхронными библиотеками.
- Сложная семантика (event-loop, await, cancellation-исключения), плохая документация и отсутствие понятных best-practice усложняют отладку и поддержку.
- Для большинства задач Python-разработчика async не критичен: WSGI/WSGI-совместимые решения, Celery, Kafka и простое горизонтальное масштабирование покрывают потребности.
- Альтернативы (trio, anyio, gevent) и другие языки (Go, Elixir) предлагают более простые модели конкурентности без «раскрашенных» функций.
I'm too dumb for Zig's new IO interface 💬 Длинная дискуссия
Zig 0.15 сменил IO: std.Io.Reader
и std.Io.Writer
.
Старый способ тормозил и путался из-за anytype
.
Подключаемся к www.openmymind.net:443
:
const std = @import("std");
pub fn main() !void {
var gpa = std.heap.DebugAllocator(.{}).init;
defer gpa.deinit();
const a = gpa.allocator();
const s = try std.net.tcpConnectToHost(a, "www.openmymind.net", 443);
defer s.close();
var wbuf: [std.crypto.tls.max_ciphertext_record_len]u8 = undefined;
var rbuf: [std.crypto.tls.max_ciphertext_record_len]u8 = undefined;
var w = s.writer(&wbuf);
var r = s.reader(&rbuf);
var bundle = std.crypto.Certificate.Bundle{};
try bundle.rescan(a);
defer bundle.deinit(a);
var tls_buf: [std.crypto.tls.max_ciphertext_record_len]u8 = undefined;
var tls = try std.crypto.tls.Client.init(
r.interface(),
&w.interface,
.{
.ca = .{ .bundle = bundle },
.host = .{ .explicit = "www.openmymind.net" },
.read_buffer = &.{},
.write_buffer = &tls_buf,
},
);
defer tls.end() catch {};
try tls.writer.writeAll("GET / HTTP/1.1\r\n\r\n");
var out: [1024]u8 = undefined;
var fw = std.Io.Writer.fixed(&out);
const n = try tls.reader.stream(&fw, .limited(out.len));
std.debug.print("read: {s}\n", .{out[0..n]});
}
Ключевые моменты
stream.reader()
иwriter()
требуют буфер.- Чтобы передать их в
tls.Client
, нужно.interface()
и&interface
. tls.Client.init
обязательно проситca
,host
,read_buffer
,write_buffer
.- Чтение ответа:
tls.reader.stream
вstd.Io.Writer
.
Комментарии (161)
- Автору пришлось вручную вызывать flush у двух обёрток и разбираться с тем, что первое чтение всегда возвращает 0.
- Основная жалоба — отсутствие документации и примеров; сообщество отвечает «читай исходники», но участники признают, что API ещё нестабилен.
- Некоторые считают новый I/O-интерфейс элегантным, но сложным даже для «Hello, world!»; другие предпочитают прямое использование системных API.
- Zig позиционируется как язык системного программирования, близкий к C, с преимуществами вроде discriminated unions и comptime, но сопровождается постоянными breaking changes.