Py-RCS를 만들던 중에…

요즘은 대구에 와서 파이썬에서 바로 RCS파일에 접근할 수 있도록 하기 위해 RCS 라이브러리 바인딩을 하고 있습니다. 제대로만 되면, 모인모인이나 ViewCVS 같은 곳에 활용할 수 있기에 정말 좋을텐데요.. 으흐

일단, Paul Eggert가 메인테인하는 RCS는 지나친 추상화와 전역변수의 과도한 사용, 자승자박 형태의 레이어 넘나들기로 인해서, 별도로 떼어 내기 매우 힘든 상태였습니다. 이 점은 CVS의 소스에서도 지적하고 있는데, Paul Eggert도 인정했다는군요.. -O-;

그리고, 그 외의 오픈소스 RCS라이브러리로 있는 것이 CVS와 Perl에 있는 VCS-RCS가 있는데 Perl은 이번 목적이 아니니 제쳐두고, CVS의 RCS Library는 비교적 깨끗한 설계 구조가 괜찮았는데, 여기서는 모두 struct RCSNode로 RCS파일 하나씩을 추상화해서 처리하고 있고, 부분파싱, 전체파싱, 부분쓰기, 전체쓰기 같은 기능을 지원하고, diff를 RCS처럼 외부 호출로 부르는 것이 아니라 직접 GNU diff를 내장 호출해서 부르기 때문에 오버헤드를 최소화했다는 점이 장점입니다.

그런데, 여기서 나타난 문제 -.-;

CVS는 일반적으로 프로그램이 곧 실행되고 끝나는 구조이기 때문에, 프로그램의 곳곳에서 에러가 나는 경우에 그냥 프로그램을 종료하는 것으로 에러를 처리하고 있습니다. 그러나, 이번에 만들 것은 파이썬 바인딩이므로 에러가 났을 때도 단지 익셉션만 내야지 프로그램을 끝내면 큰일 나겠죠;; 그래서 처리한 방법은, CVS가 GNU diff를 내장하기 위해서 사용한 방법인 “호출전에 setjmp하고 exit하는 부분에서 longjmp하기” 무공을 사용해서 처리했습니다. 우선은 그 방법으로 잘 돌아가는 듯 했으나.. 문제는 메모리, 리소스 -_-;; exit하는 판에 메모리까지 해제할 필요가 없으니.. CVS는 그냥 프로그램을 끝냈던 것.. 그러니 longjmp로 그냥 빠져나오면 메모리가 철철철새서, 1분만 열심히 돌리면 200메가짜리 덩치가 됐었습니다. 으흐.. 메모리 문제 뿐이라면 그냥 Boehm GC로 한 번 해결해 보려고 했는데, 파일을 열고 안 닫는 등 몇가지 추가적인 문제가 있어서;; (파일 디스크립터용 gc라도 만들어야할 판;)

그래서 찾은 또 다른 방법은.. RCS Library에서 exit를 호출하는 부분을 모두 패치해버리기인데, 지금 RCS Library에서 exit로 빠져나가는 부분(정확히는 error함수의 첫째 인자에 0아닌 값을 주는 곳)이 grep해보면 무려 109군데나 되어서.. 그 부분을 모두 메모리와 파일디스크립터를 해제하고 빠져나오게 고치려면.. (꾸에엑~~~)

그리고, 이 문제를 해결하더라도 CVS가 GNU diff를 호출하는 부분 역시 메모리와 파일 디스크립터를 질질 흘리고 다니는 문제점은 여전히 있어서, diff를 할 때 마다 에러가 나면 메모리가 새는 문제는 여전하게 됩니다. 앗싸아~; CVS로 큰 디렉토리 커밋하거나 체크아웃할 때 메모리를 엄청 먹는게 사실은 정당하게 먹는 게 아니라 GNU diff호출하는 부분에서 abort대신 longjmp해 버리는 바람에 메모리가 철철 새는 것이었던 것이었던 것입니다;; 무엥~

좋은 아이디어 있는 분은 꼭 알려주세요 @@~

지금까지 구현된 소스는 http://cvs.berlios.de/cgi-bin/viewcvs.cgi/yogurt/py-rcs/ 에 있습니다.

6 thoughts on “Py-RCS를 만들던 중에…”

  1. subversion같은 걸 쓰심이 =3

    음 subversion은 원래 라이브러리로 분리되어 있으니 벌써 python 인터페이스가 있으려나요?

  2. 엇. 안그래도 한 디렉토리에 1400개 파일있는 프로젝트에서 CVS 쓰느라 고생하고 있었는데 그런 엄청난 메모리 리크가 있었군요. CVS 소스를 고쳐서 업스트림에 포스트 해 주세요 =3

  3. 오오. ViewCVS는 벌써 자기 구현이 있었군요.
    음 약간 고쳐서 커밋도 되는 걸로 고쳐봐야겠습니다. 🙂
    알려주셔서 감사!

Comments are closed.