'삽질'에 해당되는 글 6건

  1. 2010/08/28 텍스트큐브 공지사항 블로그 속도 업그레이드(?) 6
  2. 2008/05/14 예외 처리는 언제나 확실하게! 1
  3. 2007/12/10 요즘 잠수타고 있는 이유 3
  4. 2007/10/22 그래서 결론 6
  5. 2007/07/07 한밤중 1
  6. 2007/06/20 삽질 2

텍스트큐브 공지사항 블로그 속도 업그레이드(?)

머리아픈 이야기 2010/08/28 03:00 by daybreaker

현재 텍스트큐브의 공지사항은 http://notice.textcube.org/ko/ 이곳을 통해 서비스되고 있습니다. 그런데 아마 아시는 분들은 아시겠지만 여기 접속 속도가 무지 느렸습니다. 페이지 하나 불러오는 데에만 5~15초 넘게 걸렸죠.;; 게다가 공지 블로그는 여러분들이 설치하신 텍스트큐브에서 관리자모드 로그인할 때 보여지도록 12시간마다 동기화되고 있기 때문에 다수의 텍스트큐브 사용자들이 이러한 속도 저하의 영향을 받을 수밖에 없었습니다.

엊그제 정말 딱 한 줄만 고쳐서 평균 접속 속도를 5~8초 가량 걸리던 것을 0.2~0.3초 정도 걸리도록 개선했습니다. 과연 무엇이 문제였을까요?

1. 텍스트큐브 자체의 속도가 느리지 않을까?
가장 먼저 해본 일이 세션 테이블을 비우는 것이었습니다. 서버 쪽에서 수십~수백 군데의 PC로부터 동시에 들어오는 HTTP 요청을 가지고 각자의 PC별로 현재 접속한 사용자를 잘 구분하여 처리하기 위해 세션이라는 것을 사용합니다. 사용자를 구분하는 것 말고도 현재 사용자의 상태에 관한 데이터를 가지고 있기도 하죠. 로그인 상태는 이 세션이 유효한 상태에서만 지속됩니다.

보통 이러한 정보를 파일 또는 데이터베이스 상의 특정 테이블에 저장하게 되는데, HTTP 특성 상 새로운 요청이 들어오지 않는다고 사용자가 웹페이지를 닫은 것인지 아니면 밥 먹으러 간 것인지 알 방법이 없습니다. (그래서 일정 시간이 지나면 개인정보 유출을 방지하기 위해 서버 쪽에서 세션을 만료시켜 자동 로그아웃되도록 해놓는 경우가 많죠) 이 만료 시간을 길게 설정할수록, 사이트의 동시접속자 수가 많을수록 서버가 동시에 유지하고 있어야 하는 세션 개수가 엄청나게 늘어나게 됩니다.

당연히 텍스트큐브 공지사항 블로그는 설치형 텍스트큐브를 설치한 온갖 곳의 서버로부터 공지사항 업데이트를 받고 있으므로 이러한 세션 수가 상당히 높게 유지됩니다. 그래서 혹시 DB가 느려져서 그런 것은 아닐까 했던 것이죠. 주절주절 썼는데 결론은 효과 없었다, 즉 이것이 원인이 아니었다는 겁니다. orz

그래서 텍스트큐브의 PHP 코드 자체가 느린 부분이 있나도 생각해봤습니다만, 같은 서버에서 동작하는 다른 텍스트큐브 및 PHP 기반 웹사이트들은 멀쩡했습니다. 그렇다면 PHP 자체의 속도가 느린 것은 아니었죠.

2. Apache 웹 서버의 속도가 느리지 않을까?
다음으로 살펴본 것은 Apache 웹 서버였습니다. 우선 시간 지연이 어떤 패턴으로 나타나는지 정확히 알아야 했기 때문에 wget, ab, Firebug 등등 온갖 벤치마킹 프로그램을 동원해서 어떤 경우에 그러한 심각한 시간 지연이 나타나는지 조사했습니다.

그 결과, 텍스트큐브가 HTML을 뿌려줄 때, 그리고 몇몇 리소스 파일(자바스크립트와 CSS)을 로딩할 때만 그런 현상이 발생하고, 서버 내에서 서버 자신으로 접속할 때는 그런 지연이 전혀 나타나지 않고 외부에서 접속할 때만 그렇다는 사실을 알아냈습니다. 또한 시간 지연은 매우 일정하게 5초 정도 발생하며, 실제 컨텐츠 전송은 시간 지연이 없으나 전송이 시작되기 전까지 기다리는 시간이 길다는 것을 알 수 있었습니다.

이러한 사실로부터, 이것이 네임서버(DNS)와 관련된 문제라는 것을 직감할 수 있었습니다. 우리가 홈페이지 주소를 입력하면 웹사이트가 뜨는 그 과정에는 홈페이지 주소를 실제 서버의 IP 주소(4자리 숫자로 된 그것)로 변환해야 하는데, 그런 변환 또는 역변환을 하는 서버가 네임서버입니다. 대부분의 웹서버들은 어떤 곳으로부터 접속이 들어왔는지 로그를 남기는데요, 이때 클라이언트의 IP 주소는 바로 알 수 있지만 그 클라이언트가 가진 도메인은 네임서버를 통해 조회해봐야만 알 수 있습니다.

그런데 이 역변환의 경우 네임서버에서 지원하지 않거나 네임서버에서 찾을 수 없는 경우 응답이 아예 돌아오지 않는 경우가 생깁니다. 그러면 웹서버는 일정 시간이 지나 timeout될 때까지 기다리고(그래야 로그를 남긴 후 웹페이지 내용을 전송할 수 있으므로), 클라이언트 PC를 사용하는 사용자 입장에서는 "응답을 기다리는 중" 상태로 그 시간만큼 똑같이 기다리게 됩니다.

그래서 첫번째로 한 것은 Apache 설정에서 네임서버를 이용하지 않도록 하는 것이었습니다. 하나의 IP 주소에서 여러 웹사이트를 서비스하기 위해 virtual host라는 것을 이용하는데 이것을 설정하는 방법에 따라 네임서버 접근이 발생할 수 있었기 때문에 이것도 모두 손보고, 텍스트큐브의 PHP 코드 내에서 자체적으로 네임서버 접근하는 부분이 있는지 검사하고, HostnameLookups 설정변수 및 로그 포맷에서 호스트 이름(도메인)이 들어가는지 모두 확인해서 제거하였습니다.

문제는 그래도 나아지지 않았다는 것이지요. T_T

최후의 수단으로 사용한 것은 strace라는 것입니다. Linux에서 시스템콜을 추적하여 로그로 남겨주는 프로그램인데, 이것을 이용하면 파일 입출력, 소켓 접근 등 운영체제의 도움을 받는 모든 부분을 다 들여다볼 수 있습니다. 네임서버에 접근하기 위해선 소켓을 이용해 인터넷에 접속해야 하므로, 웹서버가 네임서버와 어떻게 상호작용하는지 알 수 있는 것이죠. (아니면 특정 파일을 읽어야 하는데 하드디스크나 운영체제 내부적인 문제로 비정상적으로 오래 걸린다든지 하는 경우, 권한 문제인지 등도 상세히 알 수 있습니다.)

처음 시도했을 땐 웹서버의 구조 상 각각의 동시 요청을 처리하기 위해 여러 개의 프로세스를  만들도록 되어 있었기 때문에 로그가 너무 많이 나와서(간단한 텍스트 파일 하나 보여주기 위해서만도 수백개 이상의 시스템콜이 발생합니다) 분석이 불가능했습니다.

방법을 고민하던 중 니들웍스의 쿨엔지니어님이 프로세스를 한 개만 띄우도록 설정해보라고 조언해주셔서, 다른 웹사이트를 이 서버에서 모두 내리고(...) 딱 1개의 프로세스만 띄워서 얘가 notice.textcube.org에 대한 요청을 처리하도록 설정을 분리한 다음에서야 다음과 같은 데이터를 확인할 수 있었습니다.

socket(PF_FILE, SOCK_STREAM, 0)         = 16 <0.000101>
fcntl(16, F_GETFD)                      = 0 <0.000089>
fcntl(16, F_SETFD, FD_CLOEXEC)          = 0 <0.000090>
connect(16, {sa_family=AF_FILE, path="/var/run/avahi-daemon/socket"}, 110) = 0 <0.000094>
fcntl(16, F_GETFL)                      = 0x2 (flags O_RDWR) <0.000060>
fstat(16, {st_mode=S_IFSOCK|0777, st_size=0, ...}) = 0 <0.000091>
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5429003000 <0.000092>
lseek(16, 0, SEEK_CUR)                  = -1 ESPIPE (Illegal seek) <0.000099>
write(16, "RESOLVE-ADDRESS ###.###.###.###\n", 31) = 31 <0.000075>
read(16, "-15 Timeout reached\n", 4096) = 20 <5.002403>
close(16)                               = 0 <0.000068>
munmap(0x7f5429003000, 4096)            = 0 <0.000090>
stat("/var/www/needlworks/notice.textcube.org/root/ko", 0x7fffead9e930) = -1 ENOENT (No such file or directory) <0.000065>
stat("/var/www/needlworks/notice.textcube.org/root/rewrite.php", {st_mode=S_IFREG|0644, st_size=535, ...}) = 0 <0.000058>

시스템콜 함수의 이름과 거기에 전달된 인자값들이 무엇인지, 그리고 그 반환값과 수행 시간이 초 단위로 찍혀 있습니다.

맨 윗줄은 TCP 소켓을 만들었다는 뜻이고, 그 다음 connect 함수 부분은 Linux 계열 시스템에서 제공되는 avahi라는 네임서버 접근용 데몬 프로그램이 만들어놓은 파일형태의 소켓과 만든 소켓을 연결하겠다는 뜻입니다. (조금 복잡한데, Linux 계열에서는 모든 시스템 자원을 파일이라는 형태로 접근할 수 있도록 되어 있어서, 다른 프로그램과 상호작용하기 위해 위와 같은 방법을 자주 사용합니다.) 이런저런 설정과 확인을 거친 후, write 함수를 보면 어떤 IP 주소(실제로는 제가 집에서 접속할 때 사용한 유동IP입니다)에 대한 도메인을 가져오라는 내용을 쓰고 있고, 그 결과로 받은 것이 timeout, 그리고 그 결과를 받기까지 정확히 5초가 걸렸음을 보여줍니다.

네... 범인은 이거였습니다. (....)

그렇다면 웹서버가 제 의지와 상관 없이(...) 마음대로 네임서버에 접근하려다 실패하는 걸 계속 반복하고 있다는 뜻인데 왜 그런지 알아야겠지요.

약간의 구글링 끝에 알아낸 단서는, 보안을 위한 것이라지만 실제론 약간 습관적으로 사용하는 Allow from all과 관련이 있었습니다. Allow from all 자체가 이미 모든 곳으로부터의 접속을 받겠다는 뜻인데, Deny from none이라는 설정이 더 있었습니다. 그것도 텍스트큐브 관련 virtual host 설정에만요. 얼핏 보면 같은 뜻이니까 문제 없겠지 싶지만, 알고보니 none이라는 건 존재하지 않는 특수 이름이었습니다.

...그래서 "none"이라는 주소로부터 온 것인지 아닌지 검사하기 위해 모든 접속마다 IP 주소를 도메인으로 변환하려고 시도했던 것입니다. 랄랄랄라라라랄라라라... (참고로 이 일을 하는 mod_access 모듈은 다른 곳의 설정을 몽땅 무시하고 무조건 DNS 확인 절차를 수행한다고 합니다. -_-)
설정에서 Deny from none 한줄 지워주니 모든 문제가 해결되었습니다. 이 서버에서의 텍스트큐브 정상 속도대로 서비스되기 시작한 것이죠.

이상 삽질기 끝이었습니다.

아 허무해 ...ㅠㅠ
필자
author image
Daybreaker(아침놀)입니다. 현재 KAIST 전산학과에 재학 중이며 전산 외에도 물리, 음악, 건축 등에 관심이 많습니다. Needlworks 내에서는 각종 홈페이지 제작 및 서버 관리 등과 함께 Textcube 개발에 참여하고 있습니다.

홈페이지 : http://daybreaker.info

2010/08/28 03:00 2010/08/28 03:00

예외 처리는 언제나 확실하게!

머리아픈 이야기 2008/05/14 10:06 by daybreaker

정말로 오랜만의 글이로군요. 간만에 재미있는, 그러나 슬픈(...) 삽질기를 하나 들려드릴까 합니다. ㅠ_ㅠ

지금 스웨덴 교환학생의 가장 마지막 관문(?)으로 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

여러분, 저같이 애꿎은 사람 희생시키지 마시고 예외 처리할 땐 어느 예외를 받을 것인지 항상 확실하게 지정하는 습관을 들입시다~ ㅠ_ㅠ

필자
author image
Daybreaker(아침놀)입니다. 현재 KAIST 전산학과에 재학 중이며 전산 외에도 물리, 음악, 건축 등에 관심이 많습니다. Needlworks 내에서는 각종 홈페이지 제작 및 서버 관리 등과 함께 Textcube 개발에 참여하고 있습니다.

홈페이지 : http://daybreaker.info

2008/05/14 10:06 2008/05/14 10:06

요즘 잠수타고 있는 이유

머리아픈 이야기 2007/12/10 14:01 by daybreaker

....랄까, 역시 전산과에서 빡세기로 소문난 운영체제 과목 플젝이 주 원인입니다. 이거 때문에 수리물리 숙제도 매번 딜레이하고.. ㅠ_ㅠ 이른바 Heisenbug의 세계를 아주 그냥 몸소 체험하고 있습니다.;

긴 말은 필요 없을 것 같고 스크린샷 한장으로 대체합니다.;

프로젝트 작업 화면

대망의 Virtual Memory 구현 중

....요즘 24인치 하나 더 사서 듀얼 구성하면 어떨까 하는 생각이.... -_-;;;;
필자
author image
Daybreaker(아침놀)입니다. 현재 KAIST 전산학과에 재학 중이며 전산 외에도 물리, 음악, 건축 등에 관심이 많습니다. Needlworks 내에서는 각종 홈페이지 제작 및 서버 관리 등과 함께 Textcube 개발에 참여하고 있습니다.

홈페이지 : http://daybreaker.info

2007/12/10 14:01 2007/12/10 14:01

그래서 결론

즐거운 이야기 2007/10/22 14:44 by daybreaker

어제 미사 시간에 묵상을 하다가...

  1. 신의 존재에 회의를 가지기 시작한 사람이 다시 온전한 믿음으로 돌아갈 수 있을까?
  2. 이런 주제로 니들웍스 블로그에 글이나 써볼까... 요즘 철학적(?) 포스팅이 많아지는군...
  3. 로그인해야만 볼 수 있는 최호진님의 비어있는 서식 포스팅이 생각남.
  4. HTML하고 CSS를 쉽게 다룰 수 있는 방법은 없을까..
  5. Textcube.org 빨리 작업해야 되는데...
  6. Firefox, Opera, Safari는 다 잘 되는데,
  7. 그래서 결론은 망할 IE -_-

ㅠ_ㅠ

MS가 기술력이 없는 것도, 자본이나 인력이 부족한 것도 아닌데 제발 웹표준 좀 제대로 지원해줬으면 좋겠습니다. OTL
필자
author image
Daybreaker(아침놀)입니다. 현재 KAIST 전산학과에 재학 중이며 전산 외에도 물리, 음악, 건축 등에 관심이 많습니다. Needlworks 내에서는 각종 홈페이지 제작 및 서버 관리 등과 함께 Textcube 개발에 참여하고 있습니다.

홈페이지 : http://daybreaker.info

2007/10/22 14:44 2007/10/22 14:44

한밤중

따뜻한 이야기 2007/07/07 01:24 by inureyes

잠을 자야할 시간입니다. 사실 자면 안됩니다. 몸이 살짝 안좋아서 (라기보다는 잠이 부족해서) 미루어놓은 일들을 하나씩 해야 할겁니다. 기자간담회때 학교에 놓고와서 없어서 못드린 명함 대신으로 메일부터 보내야 할텐데, 네. 쥐메일을 열자마자 피곤합니다. 잠신이 들렸습니다.

이틀째 잠신이 절 놓고 놓아주지 않고 있습니다. 그래도 뭔가 해야지... 싶어서 논문 열었다가, 집에까지 와서 무슨 논문이냐 싶어 닫았습니다. 그래 놀자! 했다가 그다지 놀 거리도 없음을 발견했습니다. 결국 놀이삼아 텍스트큐브 티켓 들여다보면서 어떤 티켓이 재미있을까 고르고 있습니다.

이런 식으로 티켓 몇 장 처리했습니다. 어제 골라 잡은것 중에서 거대한 티켓이 하나 있었는데, 약빨로 그냥 끝냈습니다. 이겁니다. 거의 무아지경에서 고친 것 치고는 아직 오류가 안나와서 다행입니다. 지금도 고르다보니 이제 만만한 것은 다 끝나서 뭘 골라 잡아도 큰 일입니다.

그냥 XMLRPC ping 티켓이나 코딩해 보다가 자야겠네요. balancer이면서 creator로 여전히 외도중인 (아마도 계속 그럴것 같은) inureyes였습니다.


필자
author image
inureyes 입니다. 하고 싶은 일과 해야 할 일의 균형 맞추기를 하며 즐겁게 살고 있습니다. N/W에서는 구성을, TC에서는 교리 전파? 및 사회자?를 맡고 있습니다. 오전과 오후에는 물리학을, 저녁 시간에는 코딩을 하며 삽니다.
http://forest.nubimaru.com

2007/07/07 01:24 2007/07/07 01:24

삽질

즐거운 이야기 2007/06/20 02:31 by hojin.choi

http://dev.textcube.org/changeset/3476

저런것을 삽질이라고 하지요. 제가 한 것은 아니지만, 정규님의 정교한(?) 에디터 사용으로 빚어지는 이 놀라운 그러나 누군가는 해야했을 것들입니다.

플러그인 개발자님들께서는 앞으로 $owner를 쓰실일을 줄이시고, getBlogId() / getUserId() 이 두 함수로 적절히 나누어 사용하셔야합니다. 두 개가 너무 혼동되어 코딩된 것을 어느날 어떤 계기로 필받아서, 삽질을 합니다.

마치 삽질의 광맥을 발견한듯한 미췬듯한 손놀림.
흘러가는 시간은 어느새 두,세시간 (기본이죠)
그러나 스팀팩 맞은 듯한 정신으로 희미한 목표만 보일뿐 아무것도 거침없습니다.

결과는 뭐죠?
태터툴즈 깔아 쓰는 사람들은 아~~~무 달라지는것 없습니다.
걍, 우리 좋으라고 하는 삽질이죠.
엔돌핀 주사제가 따로 필요 없는 삽질!

저, 원래 로그인 창과 오픈아이디 로그인 창을 통합하려는거 하려다가, CK님의 홈에서 IE7상의 구글 검색이 등록되어 있지 않다는 것을 읽고나서, 곧바로 삽질 모드 들어갔습니다.
뿌라스, KLDP, dev.textcube 넣고나니, 시간은 40분이 후다닥 지나갔군요.

삽질만세!

아침이 되고 나면, 이 글 쓴것을 후회할지 모릅니다. RSS로 보시는 분들 지워졌는지 한 번 더 확인해 주셔욧!

필자
author image
텍스트큐브 외부에서 글을 써서 올릴 수 있는 BlogAPI,
텍스트큐브에 OpenID로 로그인이 가능하게 해주는 OpenID 플러그인과,
번역자들이 쉽게 번역할 수 있도록하는 다국어 지원 구조를 담당합니다.
회사에서는 오픈아이디 서비스(idtail.com)를 개발하고 있으며,
그 외의 관심사는 PHP 프레임웍인 CakePHP, 테스트주도 개발,
자동 빌드 시스템, 형상관리 소프트웨어 및 실무적용,
안티스팸, 리눅스 커널, 암호화 라이브러리 등에 있습니다.
<a href="http://coolengineer.com/">블로그</a>

2007/06/20 02:31 2007/06/20 02:31