이하의 글은 2012년에 쓴 것입니다. 오래된 글인 만큼, 현재의 생각과 전혀 다른 내용도 많이 포함되어 있고, 당시와는 상황이 많이 달라진 점도 있습니다. 또한, 그 당시에 잘못 알려졌던 정보도 포함되어 있을 수 있습니다. 어찌됐든 저는 제 오래된 글이 회자되는 것을 저어합니다. 읽기에 앞서 양해를 부탁드립니다.
비동기 I/O 라이브러리 아이디어
요즘 gevent
등의 비동기 I/O 라이브러리들을 쓰면서 생각하고 있는 새 비동기 I/O 라이브러리 디자인 아이디어들이 있다. 일단 크게 두 라이브러리로부터 영감을 얻었다.
- Twisted
- Twisted가 오래됐는데도 불구하고 여러 부분에서 봤을 때 가장 잘 디자인되어 있다. Twisted가 다 잘해둔 것들을 오히려 나중에 가서 그보다 못하게 리엔지니어링하면 안된다.
gevent
- 코루틴을 이용하여 직렬적인 루틴은 CPS 없이 자연스럽게 쓸 수 있어야 한다. node.js처럼 하면 안된다.
이미 있던 것들과 전체적으로는 비슷하고, 중요한 부분만 적자면:
…
Python 2.5에서 들어온 강화된 제너레이터(enchanged generators)는 사실 코루틴이다. CPython, PyPy, Jython 등의 여러 구현체에서 모두 쓸 수 있도록 Greenlet 같은 것을 쓰지 말고 강화된 제너레이터를 사용한다.그런데 좀 생각해보니 제너레이터는 다 좋은데yield
를 항상 써야 해서 맨 아래 항목에서 언급할 멍키패쳐를 구현할 수 없다. 대신 CPython에서는 Greenlet를 쓰고 Stackless Python과 PyPy에서는stackless
모듈을 쓰는 방향으로 가야할 것 같다.Twisted가 세상에 존재하는 리액터/IO 루프의 공통적인 부분을 찾아서 일반적인 인터페이스를 정의한 뒤, 그 인터페이스의 다양한 구현을 포함한 것은 매우 훌륭한 결정이라고 생각한다. Twisted는
select
, 쓰레드select
, IOCP, kqueue, epoll 등 뿐만 아니라 심지어 GTK, GTK 2, Qt 메인루프까지 일반 인터페이스 아래 죄다 구현해뒀다. GTK 등은 사실 GUI 애플리케이션에서 비동기 I/O를 구현하기 위해 필요한 것으로 서버 구현에서는 필요 없겠지만, 일반적인 인터페이스가 있다면 저런 것도 구현이 가능한 것이다. 그리고 라이브러리를 사용한 애플리케이션 코드는 플랫폼 이식성이 매우 높아진다.그런 가운데
gevent
가 하듯 표준 라이브러리의 I/O 모듈을 갈아치우는 멍키패쳐를 제공해야 한다. 안 그러면 아무리 코루틴을 써도 이미 존재하는 거의 모든 라이브러리에서 블럭이 되기 때문에 자동으로 모든 코드가 동기화되어버린다.
요는 Twisted의 이식성과 gevent
의 사용성 모두가 필요하다는 것. 아직 아이디어 수준이고 실제로 구현하게 될지는 아직 모르겠다.