러스트(Rust) 언어의 비동기(async) 프로그래밍 모델은 고성능 동시성 애플리케이션 개발에 필수적이지만, 스케줄러가 언어 자체에 내장되지 않고 라이브러리(크레이트) 형태로 분리되면서 개발자들 사이에서 많은 불만과 논쟁을 낳고 있습니다. 이는 임베디드(embedded) 환경 지원, 제로 비용 추상화(zero-cost abstraction) 등 러스트의 핵심 설계 목표를 달성하기 위한 선택이었으나, 동시에 런타임 간 호환성 문제, 복잡한 타입 제약, 그리고 예측하기 어려운 동작 방식이라는 대가를 치르고 있습니다.
가장 큰 문제 중 하나는 'Tokio 중심주의'로, 가장 널리 사용되는 비동기 런타임인 토키오(Tokio)에만 해당하는 특성이 마치 async Rust 전체의 특성인 것처럼 오인되곤 합니다. 특히 `tokio::spawn`과 같은 함수는 스레드 로컬(thread-local) 실행 문맥에 암묵적으로 연결되어, 해당 문맥이 없으면 런타임 패닉을 일으킬 수 있습니다. 이는 같은 함수라도 호출되는 스레드에 따라 동작이 달라지는 예측 불가능성을 초래하며, 개발자가 의도치 않은 오류를 만나게 합니다. 또한, 비동기 함수의 상태를 담는 퓨처(Future)의 크기가 중첩될수록 기하급수적으로 증가하여 스택 오버플로(stack overflow)를 유발할 수 있다는 점도 중요한 문제입니다. 이는 퓨처가 비동기 함수의 상태 머신(state machine)으로 컴파일되기 때문입니다.
이러한 복잡성은 비동기 프로그래밍 자체의 난제와 러스트의 독특한 설계 철학이 결합된 결과입니다. 러스트는 가비지 컬렉션(garbage collection)이나 암묵적인 참조 카운팅(reference counting) 없이 메모리 안전성을 보장하며, 저수준 제어와 고성능을 동시에 추구합니다. 따라서 고(Go) 언어의 고루틴(goroutine)처럼 언어 자체에 내장된 런타임과 그린 스레드(green thread)를 제공하기보다는, 개발자가 사용 사례에 맞춰 최적의 스케줄러를 선택하고 초기화하도록 유도합니다. 이는 임베디드나 `no_std` 환경과 같은 특수 목적에 매우 유리하지만, 일반적인 서버 애플리케이션 개발자에게는 더 높은 학습 곡선과 디버깅의 어려움을 안겨줍니다. 결국 async Rust의 복잡성을 해소하기 위해서는 동시성 고유의 문제와 라이브러리 형태 런타임의 문제를 명확히 구분하고, 언어 기능 개선과 함께 개발자 교육 및 생태계의 성숙이 필요합니다.