'Python'에 해당되는 글 2건
- 2008/05/14 예외 처리는 언제나 확실하게! 1
- 2007/05/31 호환성 유지하기 2
예외 처리는 언제나 확실하게!
머리아픈 이야기 2008/05/14 10:06정말로 오랜만의 글이로군요. 간만에 재미있는, 그러나 슬픈(...) 삽질기를 하나 들려드릴까 합니다. ㅠ_ㅠ
지금 스웨덴 교환학생의 가장 마지막 관문(?)으로 Musical Communication and Music Technology라는 매우 긴 이름을 가진 과목의 기말 프로젝트를 하는 중입니다. 발표는 오늘(!)이지만 프로젝트 기간 자체가 워낙 짧았던 데다 같이 하는 애들이 지난 주에 시험이 계속 겹치는 등의 이유로 실제 진행은 거의 3일 벼락치기로 하는 중이지요;;;
과목 이름에서 유추할 수 있듯 프로젝트 내용은 상당히 '미디어 아트'적인 내용입니다. 과제로 했던 Lab에서 마지막에 했던 것이 실시간 비디오프로세싱 프로그램인 EyesWeb을 이용하여 사람의 동작을 웹캠으로 찍어 음악을 컨트롤하는 내용이었는데, 그것을 좀더 확장하기로 한 것이지요. 처음엔 막연히 뭘 더 넣을 수 있을까 고민하다가 요즘 한창 유명해진 니코니코조곡 오토마리오 버전 동영상을 보고 실제 몸의 움직임을 추적하여 실제 사람이 연기하는 마리오를 만들면 재밌겠다 싶어서 그쪽으로 방향을 잡았습니다. (그게 어젭니다-_-)
수업 때 소리를 컨트롤하는 프로그램으로 실시간 소리 합성이 가능한 오픈소스 사운드 프로그래밍 툴인 Pure Data를 이용했는데, 이게 사운드 생성은 쉬워도(?) 기존에 녹음된 사운드를 재생하는 것이 난감하더군요.; 그래서 EyesWeb에서 Open Sound Control(이하 OSC)이라는 프로토콜을 이용해 UDP로 쏴주는 메시지들을 직접 받아 소리 재생을 하는 프로그램을 짜면 어떨까 싶었습니다.
자, 서론이 길었습니다.<br/> 제가 요즘 유용하게 이곳저곳 잘 써먹는 Python을 이용하기로 했고, 크로스플랫폼 소리 재생을 위해 pygame 라이브러리를 써서 쉽게 소리 재생을 할 수 있었습니다. 또한 OSC 프로토콜을 파싱해주는 것도 이미 Python으로 구현되어 있었기 때문에 그 라이브러리를 가져다 쓰니 통신도 금방 구현할 수 있었지요. 근데 갑자기 어느 순간부터, EyesWeb에서 계속 쏴주고 있는 UDP 데이터를 못 받고 block되어버리는 겁니다.
EyesWeb 문제인가 싶어서 데이터 전송 속도를 줄여보기도 하고, 파일을 새로 만들어보기도 했고 윈도우 문제인가 싶어서 방화벽에 UDP 포트 추가도 해보고 심지어 패킷스니핑 프로그램까지 썼습니다.;; 또 OSC 라이브러리 문제인가 싶어서 멀티쓰레드로 된 구현을 싱글쓰레드로 바꿔보기도 하고 별의별 짓을 다 해봤지요. 일단 혐의(?)는 소켓 쪽에 문제가 있을 것으로 생각하고 있었습니다.
근데 여기가 스웨덴이다보니, 저보다 Python을 잘 하시는 퍼키군님과 같은 다른 사람들의 도움을 요청하자니 다들 자고 있을 시간이더군요. -_-; 혼자 힘들게 구글링하며 온갖 삽질을 다 하다가, 결국 가장 원시적인 디버깅 방법, 즉 print 찍어보기를 해봤습니다. 그리고 1분만에 좌절했습니다. (........)
원인은 세 가지였습니다.
- pygame.mixer.get_busy()를 이용해 현재 재생 상태를 알아내는 부분이 있는데, is_busy()라는 잘못된 이름의 함수를 썼습니다. (이건 전적으로 제 잘못입니다..orz) 근데 이 부분이 항상 실행되는 게 아니고, 받아온 모션캡처 데이터에 따라 반랜덤하게 실행되는 곳이었죠.
- OSC 라이브러리가 멀티쓰레드로 돌며 제가 지정한 핸들러 함수를 호출해주는 방식이었습니다. 따라서 그 안에서 뭔 일이 발생하여 죽더라도 프로그램은 죽지 않았습니다.
- OSC 라이브러리 내부 코드에서 핸들러를 호출하는 부분을 try-except 구문이 둘러싸고 있었는데, 그 except 구문에 어떤 예외를 받을지 지정이 되어 있지 않았습니다. 즉, 모든 예외를 다 받겠다는 것이었죠.
자, 이쯤에서 무슨 일이 벌어졌을까요?
잘못된 이름의 함수를 썼으니 당연히 예외가 발생하여 프로그램이 죽어야 할 것입니다. 하지만 그 예외를 라이브러리 코드 내에서 먹어버렸고, 불행히도 그 try-except가 소켓 데이터를 읽는 while 루프 바로 바깥이라서 루프가 종료되고 결과적으로 해당 쓰레드는 아무 일 없었다는 듯 '정상 종료'를 했습니다. 하지만 메인 프로그램은 계속 돌고 있었죠. 화면에는 아무것도 나오지 않습니다. 게다가 그 잘못된 함수를 호출하는 순간은 제가 카메라 앞에서 어떤 동작을 하느냐에 따라 달라지니 에러가 랜덤하게 발생하는 것처럼 보였던 겁니다. (위에서, 싱글스레드로 바꿔보기도 했다고 썼는데, 이 경우에도 랜덤 발생으로 보였던 겁니다. 게다가 프로젝트 듀가 급하니 마음도 급했던지 차분하게 생각하지 못했던 것도 문제였죠.)
그래서......인생이란 삽질인 것입니다. OTL
여러분, 저같이 애꿎은 사람 희생시키지 마시고 예외 처리할 땐 어느 예외를 받을 것인지 항상 확실하게 지정하는 습관을 들입시다~ ㅠ_ㅠ
호환성 유지하기
머리아픈 이야기 2007/05/31 13:54좀 규모가 되는 프로그램들을 짜보신 분들은 알겠지만 하위 호환성을 잘 지원한다는 건 정말 어려운 일입니다. 이 일은 프로그램 자체 기능들의 하위 호환성을 유지하는 것과, 프로그램이 돌아가는 환경과 프로그램의 하위 호환성을 유지하는 것으로 나눠볼 수 있는데, 전자는 사실 그렇게 어려운 건 아닙니다. (물론 그 프로그램이 Windows 정도 되는 OS라면 또 얘기가 달라집니다만..)
문제는 후자의 경우입니다. 사실 태터툴즈가 굉장히 많은 버그를 떠안게 된 것도 그런 연유이죠. 사실 이 문제는 모든 '배포형 웹프로그램'에서 나타나는 현상입니다. 서버 환경 자체가 워낙 다양하기 때문에, 또 같은 환경(같은 php 버전, 같은 mysql 버전, ...)이더라도 설정을 어떻게 했느냐에 따라 동작이 달라지기도 하죠. (특히 php의 경우 그것이 두드러집니다)
PHP 5와 MySQL 4.1 이상 환경이 사실 처음 태터툴즈 소스를 만지게 된 우리가 가장 이상적으로 봤던 환경입니다. OOP도 좀더 제대로 사용할 수 있고, UTF-8 문자열도 문제없이 처리할 수 있고 등등요. (참고로 말하자면 MySQL 4.0과 4.1에서 꽤 많은 변화가 있었습니다. utf-8 지원도 그렇고, password 함수의 알고리즘 변경 등이 있었는데, 특히 password 함수가 바뀐 덕분에 제로보드와 호환성 문제가 발생하게 되어 많은 호스팅업체가 4.1 이상으로 넘어가지 않는 결과를 초래하고 말았죠. 사실 mysql 데몬을 띄울 때 옵션을 줄 수 있긴 합니다만..)
한때 내부에서는 태터툴즈를 Python으로 만드는 게 어떻겠냐는 의견도 나왔었습니다. PHP 언어의 한계나 인터프리터 구현의 버그 등으로 인해 우리 입맛에 맞게 쓰는 게 매우 힘들었죠. (특히나 OOP 방향으로 개발하면서 더욱 php에 실망을 많이 했습니다.) 제가 Python을 본격적으로 접하게 된 건 그보다 뒤의 일입니다만, 현재 만드는 사이트는 웬만하면 Python + Django 프레임웍 조합을 사용할 정도로 그 편리함과 깔끔함에 빠져 있습니다. (needlworks.org도 Django 기반입니다. 물론 아직 기능은 별 것 없지만...-_- 참고로 구글도 Python으로 많은 수의 웹페이지를 구성하고 있습니다. Django를 쓴다거나 그런 건 아니고 자체적으로 Python 및 웹서버 구조를 커스터마이징했을 거라고 추측됩니다.)
언어의 깔끔함이나 그런 걸 제쳐두고라도, Python의 경우 상당히 오랫동안 안정화가 되었기 때문에, 더 이용하려고 했던 점도 있습니다. (근본적인 언어 설계의 차이에서 오는 것도 크지요.)
그러나 Python의 Django, PHP의 CakePHP, Ruby의 Rails 등을 쓸 경우 가장 큰 문제는 배포입니다. 사이트 하나를 구축하기 위해서 사용할 때는 매우 편리한 환경을 제공하지만, 그 환경을 설정할 때 root 권한이 필요한 경우도 있고 웹서버의 설정을 건드려야 하는 경우도 있어서 배포용 프로그램에는 적합하지 않죠. 그 점에서만큼은 아직 PHP를 따라올 만한 것이 없습니다. (가장 많은 웹호스팅에서 지원하고 있기도 하구요.)
요즘 학교에서 Key 인증서버 구축을 완료한 덕분에 Windows Vista Enterprise 64bit용을 써보고 있는데, Microsoft가 독점이니 뭐니 해도 하위호환성만큼은 정말 잘 지켜내고 있다는 생각을 금할 수 없습니다. (물론 일반사용자 입장에서 보면 아니라고 할 수 있겠지만, 개발자의 입장에서 보면 정말 대단합니다.) 64비트 환경에서 32비트 프로그램을 실행할 수 있도록 모든 시스템 dll들을 32/64비트 버전을 따로 제공하고 있는 점, 기본으로 접근할 수 있는 Internet Explorer 7을 일부러 32비트용으로 해놨다는 점(Flash player 등은 아직 64비트에서 동작하지 않습니다) 등은 정말 Microsoft 급의 규모가 아니면 하기 힘든 일입니다. Windows 3.1에서 95로 넘어올 때 심시티 2000이 제대로 실행되게 하기 위해서 메모리 해제 함수를 특수 모드로 동작하게 했다는 이야기도 있죠.
Windows의 그 막강한 하드웨어 호환성도 Linux를 여러 번 설치해본 사람이라면 매우 부러워할 만한 부분입니다. 역설적으로 거의 독점하다시피 하는 Microsoft이기에 가능한 부분이기도 하죠. 얼마 전 동아리 서버가 뻑나서 새 CPU와 메인보드를 구입해 Linux를 설치하다가 호환성 문제로 3일 내내 삽질하고 쥐쥐쳤던 걸 생각하면 정말...ㅠ_ㅠ;
아무튼, 웹 환경에서 배포용 프로그램을 개발할 때의 가장 난점이 호환성입니다. 상위호환성은 거의 불가능하다 치더라도 하위호환성을 맞추는 것도 쉽지 않습니다. 태터툴즈의 경우는 PHP와 MySQL 버전이 낮은 환경에서도 잘 실행될 수 있도록 하기 위해 성능을 희생한 부분이 꽤 많습니다. (티스토리의 경우는 서비스이기 때문에 서버 환경을 마음대로 정할 수 있으므로 이런 부분에서 꽤 많은 성능을 끌어올린 것으로 알고 있습니다.) 개인적으로는 제로보드가 그 막강한 시장 영향력(?)을 잘 행사해서 웹호스팅 환경의 꾸준한 업그레이드를 유도해왔다면 훨씬 개발이 편했을 거라는 생각도 해봤지요.
개인사용자용 TextCube에서는 크게 고려할 만한 부분은 아니지만, 요즘 겐도님의 글과 최재훈님의 글을 보면서, 또 Vista를 쓰기 시작하면서 아키텍처와 호환성에 관해 이런저런 생각이 많이 듭니다. (Flickr가 PHP 4와 MySQL 4를 이용하고 있다는 점이 특히 놀라웠습니다. ^^;)
비밀방문자 2014
inureyes 2014
비밀방문자 2013
화사함 2012
LonnieNa 2010