6. Popclient가 Fetchmail이 되다.

fetchmail 프로젝트에서 큰 전환이 일어났던 것은 해리 호흐하이저(Harry Hochheiser) 가 클라이언트 머신의 SMTP 포트로 메일을 포워딩하는 대략적인 코드를 보내준 때였다. 보자마자 이 기능을 안정적으로 구현한다면 다른 모든 배달 방법은 구식이 되리라는 것을 깨달았다.

여러 주 동안 나는 fetchmail을 조금씩 뜯어고치고 있었는데, 인터페이스 설계가 작동하긴 하지만 지저분하다고 느끼고 있었다. 우아하지도 않고 몇 안되는 옵션들이 너무 여기저기 흩어져 있었다. 가져온 메일을 메일박스 파일에 부어놓을 것인지, 표준출력으로 내보낼 것인지 결정하는 옵션이 특히 골치거리였지만 왜 그런지 확실히 깨닫지는 못했다.

SMTP 포워딩을 생각하자 그동안 popclient 가 너무 많은 것을 해내려고 했다는 것을 알게 되었다. poopclient 는 MTA (Mail Transport Agent) 와 MDA (Mail Delivery Agent)의 기능을 모두 가지도록 설계되었다. SMTP 포워딩만 할 수 있다면 MDA 기능을 없애 순수한 MTA 가 될 수 있었다. sendmail 과 마찬가지로 최종적인 메일 배달은 다른 프로그램에게 맡기면 되는 것이다.

TCP/IP를 지원하는 플랫폼이라면 거의 어디에나 25번 포트가 기다리고 있는데 무엇 때문에 복잡한 MDA 기능을 설정하거나 메일박스를 잠그고 덧붙이는 (lock-and-append) 문제를 가지고 고생을 하는가? 더구나 포워딩을 사용하면 가져온 메일이 평범한 SMTP 메일처럼 보일 것이고, 우리가 원하는 것이 바로 그것이었는데 말이다.

몇가지 배울 점이 있었다. 먼저, SMTP 포워딩에 대한 아이디어는 내가 리누스의 방법을 모방하려고 의식적으로 노력한 것에 대한 가장 큰 보답이었다. 사용자 한 명이 내게 끝내주는 아이디어를 주었으며 내가 해야했던 일은 그 의미를 이해하는 것 뿐이었다.

11. 좋은 아이디어를 생각해내는 것 다음으로 중요한 일은 사용자들이 알려준 좋은 아이디어를 깨닫는 것이다. 때로는 이편이 더 나을 수도 있다. (The next best thing to having good ideas is recognizing good ideas from your users. Sometimes the latter is better)

흥미롭게도 만일 당신이 얼마나 다른사람에게 빚을 많이 지고 있는지를 자기 비하라고 느껴질 정도로까지 솔직하게 털어놓는다면 대개의 사람들은 당신이 혼자서 거의 모든 일을 해내고서 천재성에 대해서 겸손해 하는 것처럼 대한다는 것을 곧바로 알게 될 것이다. 리누스의 경우를 보라! (1997년 8월, Perl 컨퍼런스에서 이 글을 발표할 때 래리 월이 첫 번째 줄에 앉아 있었다. 바로 윗 줄에 도달했을 때 그는 부흥사라도 된 것처럼 외쳤다. ``형제여, 이야기 하시오, 이야기를!'' 청중들 모두가 이것이 Perl을 만든 래리에게도 적용된다는 것을 알았기 때문에 웃음을 터뜨렸다.)

똑같은 정신으로 프로젝트를 몇 주 진행해 나가자 나는 사용자들 뿐 아니라 이야기를 전해들은 다른 사람들로부터 비슷한 칭송을 받기 시작했다. 나는 그런 email 중 몇몇을 따로 보관해 두었다. 나중에 내 삶이 가치있는 것이었는지 의심스러워질 때 그 메일들을 다시 꺼내볼 생각이다. :-)

모든 종류의 설계에 대해서 적용될 수 있는 두가지 더 기본적이며 비정치적인 교훈이 있다.

12. 종종 가장 충격적이고 혁신적인 해결책은 당신 자신이 문제에 대해서 가지고 있는 개념이 잘못되어 있다는 것을 깨닫는 것에서 나온다. (Often, the most striking and innovative solutions come from realizing that your concept of the problem was wrong)

나는 popclient를 MTA/MDA 기능을 다 갖추고 복잡한 지역배달모드들까지(local delivery modes) 갖춘 것으로 개발해 나가면서 틀린 문제를 풀려고 노력하고 있었다. fetchmail의 설계는 가장 기초적인 것부터 재고하여 SMTP 포트로 메일을 배달하는 인터넷 메일 경로의 한 부분인 순수 MTA 가 되어야 했다.

개발 도중에 벽에 부딪친다면 - 다음번 패치 후에 무엇을 해야 할 지 모르겠다면 - 그때는 정답을 가지고 있는지 생각할 것이 아니라 질문이 올바른 것인지 의문을 가져보아야 하는 경우가 종종 있다. 아마도 문제의 틀을 다시 잡아야 할 것이다.

그래서, 나도 내 문제의 틀을 다시 잡았다. 분명히 제대로 일을 진행하려면 (1) SMTP 포워딩 지원 기능을 일반 드라이버에 포함시키고, (2) SMTP 포워딩을 기본모드로 만들고 (3) 최종적으로는 다른 배달모드들, 특히 `파일로 배달하기' 와 `표준출력으로 배달하기'를 제거해야 했다.

나는 단계 (3)에서 조금 머뭇거렸는데, 이유는 오랫동안 popclient 를 써오면서 다른 배달모드에 의존하고 있을 사용자들의 심기를 불편하게 만들고 싶지 않았기 때문이다. 이론적으로는 그들 모두 즉시 .forward 파일이나 sendmail 외의 비슷한 프로그램으로 전환하여 동일한 결과를 얻을 수 있었다. 실제로는 전환 자체가 큰 일이 될 것이었다.

하지만 단계 (3)을 실행하고 나자 이점이 매우 큰 것으로 나타났다. 드라이버 코드 중 가장 힘든 부분이 사라졌다. 설정이 엄청나게 간단해졌다 - 시스템의 MDA 와 사용자의 메일박스를 일일이 찾아다니며 굽실거릴 필요도 없어졌고, OS 가 파일 잠금을 지원하는지 걱정할 필요도 없어졌다.

게다가 메일을 잃어버릴 한가지 가능성도 사라졌다. `파일로 배달하기'를 선택했을 때 디스크가 꽉 차 있으면 메일이 사라져 버렸던 것이다. SMTP 포워딩에서는 SMTP 리스너가 메시지 배달이 가능하거나 나중에 배달할 수 있도록 스풀해 놓기 전에는 OK를 돌려주지 않을 것이기 때문에 이런 일이 일어날 수가 없다.

성능도 향상되었다(한두번 실행시켜서는 느끼지 못하겠지만). 또 변경에 따르는 그다지 중요하지 않은 이익이라면 매뉴얼 페이지가 훨씬 간단해 졌다는 것이다. 나중에 나는 사용자가 지정한 지역 MDA를 통해 배달하는 기능을 다시 넣어야 했다. 동적인 SLIP를 포함하여 몇몇 애매한 상황을 다루어야 했기 때문이다. 하지만 처음보다 훨씬 간단한 방법을 찾아낼 수 있었다.

교훈이라면? 낡아서 사용할 수 없는 기능이라면 효율을 떨어뜨리지 않고 제거할 수 있을 때는 망설이지 말고 제거해 버리라. 앙뜨완 드 생떽쥐뻬리는 (아동서적 작가였으며 남는 시간에는 비행기 조종과 설계를 했던) 이렇게 말했다.

13. ``(설계에 있어서) 완벽함이란 더 이상 추가할 것이 없을 때 이루어지는 것이 아니라 더 이상 버릴 것이 없을 때 이루어진다. (Perfection (in design) is achieved not when there is nothing more to add, but rather when there is nothing more to take away)''

코드가 더 나아지고 간단해지고 있을 때가 바로 일이 제대로 되어가고 있다는 것을 알게 되는 때다. 그리고 그 과정에서 fetchmail 의 설계는 그 조상격인 popclient 와 다른, 자신만의 정체성을 획득했다. 이름을 바꿀 때가 된 것이다. 새로운 설계는 예전의 popclient 보다는 sendmail 과 비슷해 보였다. 둘다 MTA였으나 sendmail은 푸시(push) 후에 메일을 배달했고 새로운 popclient 는 풀(pull) 후에 메일을 배달했다. 해서 두 달 후에 나는 popclient 의 이름을 fetchmail로 변경했다.