2009년 10월 14일
간단한 alarm module의 간단하지 않은 예상

저희 팀에서는 Lego block과 같은 s/w의 단위를 module이라고 부릅니다.
alarm이라는 module을 작성하기로 하였죠.
alarm이란 매우 간단한 기능입니다.
예를 들어, 2009년 11월 11일 9시 00분 00초에 어떤 일을 하도록 하는 기능이죠.
구현하는 입장에서 보면
현재 시간을 계속 지켜 보다가 설정한 시간과 같으면 등록한 function을 불러주면 됩니다.
휴대폰에서 사용하는 알람 기능이나
Windows에서 사용하는 스케줄러 혹은 구글 캘린더에서 지원되는 흔한 기능입니다.
Linux/Solaris사용자라면 익숙하신 crontab의 기능과도 비슷하고요.
'하루면 끝낼 수 있겠다~' 하고 시작을 합니다.
작업을 하다 보니까, alarm의 기능이란 정확히 말해서는 반복 기능도 포함되더군요.
예를 들어 '매시 00분 00초에 무슨 일을 해라~' 와 같은 기능을 수행해야 합니다.
조금은 복잡해 보이지만, 이틀이면 끝낼 수 있을 것 같습니다.
조금 더 작업을 하다 보니, 반복에는 이런 기능도 필요하다는 것을 알게 되었습니다.
매달 말일에, 혹은 마지막 주의 금요일에 뭔가를 하라는 기능이죠.
정리를 해보니까, 매분, 매시, 매일, 매주, 매달, 매년 식의 기능이 필요하더군요.
이중에서도 매달의 경우에는 이런 방법도 됩니다.
매달 25일, 이건 쉽군요.
반면 요일을 사용하는 경우에는 조금 복잡해집니다.
매달 1번째 수요일, 매달 1번째 주일 (월-금), 매달 마지막 금요일 등과 같이 말입니다.
게다가 2주에 한번 과 같은 기능도 필요하고요.
구현 자체는 해 볼만 한데, 이것을 어떻게 API로 만들지가 고민입니다.
structure형태로 만들다 보니, 참으로 복잡해 지는 군요.
모든 기능을 추가해서 만들어 보니, '이 복잡한 것을 누가 쓸까?' 하는 생각이 듭니다.
게다가 1.1 버전에서 upgrade가 필요하게 되면,
backward compatibility를 지원하는 것이 힘들어 보입니다.
'backward compatibility를 지원하면서도,
쉽게 사용할 수 방법이 없을까?'
생각해낸 것은 시간을 string으로 표현하는 방법입니다.
예를 들어, 매 2주 간격으로 수요일 9시 00분 00초에 를 아래와 같이 표현하는 거죠.
"2 weekly wed 09:00:00"
string이기 때문에, 새로운 형태가 필요하면 쉽게 추가할 수 있습니다.
게다가 직관적이라서, 사용자는 행복할 것 같습니다.
그런데 개발자는 걱정이 태산입니다.
이미 일주일이 지나버렸고, "2 weekly wed 09:00:00" 과 같은 string을 처리하려면
parser도 작성을 해야 되기 때문이죠.
하루면 끝날 것 같았던 module이 1주일을 벌써 넘기고,
앞으로도 적어도 1~2주는 더 써야 할 것 같군요. 이것 참...
alarm 발생 부분의 동작부분은 간단합니다.
시간을 보면서 2009년 11월 11일 9시 00분 00초가 되면 alarm을 발생시키면 됩니다.
그런데 실제로 해보니, 8시 59분 59초에서 한번 돌고, 9시 00분 01초에 program이 도는 경우가
있더군요. 이런 CPU를 받지 못하는 starvation이 발생하기 때문에
시간이 같은지 만을 확인해서는 alarm을 발생시키지 못하는 버그가 발생합니다.
대신 시간을 비교해서, alarm 설정시간이 현재 시간보다 크거나 같으면 발생시켜야 합니다.
그런데, 시간을 비교하는 것이 생각만큼 간단하지 않습니다.
년,월,일,시,분,초를 모두 비교하다 보니,
time을 관리하는 module이 있으면 좋겠다는 생각이 듭니다.
마음이 급하지만, time module을 하나 더 만들기로 합니다.
이왕 하는 것, 2개의 time을 비교하거나, 더하거나, 빼거나 하는 기능도 만들기로 합니다.
현재의 시간을 읽는 interface도 추가를 하고요.
길어야 하루면 될 것 같습니다.
time module을 만든 후에 alarm에 적용을 하니,
CPU를 받지 못하는 starvation이 어느 정도 발생하여도 잘 동작합니다.
다행입니다.
하나의 alarm은 이제 잘 동작하니, 반복 alarm을 구현하고 시험합니다.
다행히, 반복기능의 구현은 쉬웠습니다.
그런데 시험을 하려고 하니, 막막합니다.
매분 alarm을 시험하려면 3~4분 기다리면 되지만,
매시 alarm을 시험하려면 3~4시간을 기다려야 합니다.
그 정도면 할만하지만 매주 alarm은 너무 길군요.
게다가 매월, 매년을 어떻게 시험합니까?
그렇다고 시험도 안 한 module에 완성이라는 도장을 찍을 수는 없고요.
이제 막바지인데, 마음이 답답해 지는 군요.
결국 생각해 낸 것은, '시간을 어떻게 빨리 흐르게 할 수 없을까?' 하는 것이었습니다.
alarm module은 현재시간을 time module로부터 얻기 때문에,
time module에서 현재 시간보다 조금 더 빠르게 시간을 넘겨주면
짧은 시간내에 시험이 가능할 것도 같았습니다.
결국 time module을 upgrade하여, 시간을 몇 배속으로 흐르게 하는 기능을 추가하였습니다.
10배, 100배, 1000배로 시간을 흐르게 하면서 시험을 하는 것이죠.
며칠 전에 time간에 빼거나 더하는 기능이 있어서 쉽게 구현을 했습니다.
시작한 시간에서 현재 시간을 뺀 다음, 여기에 몇 배를 곱한 후에, 다시 더하면 되더군요.
근데 적용을 해보니, alarm module의 시험에는 여러 가지 속도의 시간이 필요합니다.
매일은 10배라면, 매주는 100배, 매달은 1000배 이런 식이죠.
그러다 보니, 10배로 돌다가, 그 다음에 100배로 돌고 하는 연속 기능이 필요하더군요.
time module을 upgrade하는데 또 하루가 지나갑니다.
휴우~, 하루면 될 줄 알았는데, 벌써 한 달이 다되어 갑니다.
그나마 alarm module은 거의 완성이 되어 실제 프로젝트와 integration을 하였습니다.
예상대로 잘 동작합니다. 그렇게 시험을 했으니 잘 돌지 않을 이유가 없죠.
근데, alarm module사용자가 현재 설정된 alarm을 조회할 수 있는 기능을 원하더군요.
쉬운 기능이라고 하며 아래의 string의 list를 넘겨주었습니다.
"2 weekly wed 09:00:00"
사용자는 string을 받아 들고는 황당한 얼굴을 합니다.
UI 스케줄러에 표시를 해야 하는데, '제가 이걸 parsing해야 합니까?' 하는
결국 사용자는 structure 형태의 (XML이던, API던) data를 원했고,
설정은 string으로, 조회는 structure로 하는 일관성이 깨진 interface가 되어 버립니다.
일관성을 위해서는 structure로 설정과 조회를 하면 좋겠지만,
string이 사용하기 편하다는 이유로 그대로 놓아두고 맙니다.
사실 마음속 한구석에서는 이런 말을 하고 있는지도 모르겠습니다.
'parser를 작성하며 사용한 2주의 시간을 의미 없이 버릴 수는 없자나...'
간단해 보이는 alarm module하나도
가보지 않은 상태에서 그것을 예상하기란 참으로,
간단하지 않은 일 같습니다.
고맙습니다.
제임스 드림
# by | 2009/10/14 00:12 | 메인스토리 | 트랙백(1) | 덧글(29)





☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
제목 : 엽우의 생각
소프트웨어 이야기 : 간단한 alarm module의 간단하지 않은 예상 - 소프트웨어 공학이 필요한 사례를 잘 보여주는 글. 읽다 보면 매우 공감이 된다....more
시간 관리 모듈에서 국제 시각도 도입하고 서머 타임까지 고려 해야 한다면..
그래도 block이란 단어를 계속 쓰기는 해야 될 것 같아요.
이 곳에서 brick은 아무래도 '오륀지' 같은 느낌이라… 하하
맞습니다. 쉬워 보이는 것들이 직접 해보면 왜 그리 다 어려운지,
하면 할수록 실력의 한계가 느껴지는 가을이네요.
object님의 천재적인 실력이 또 부러워지고요 ^^
현실을 잘 반영하신 글 같네요.
끊임없이 변하는 요구사항들과...
특히.. 'parser를 작성하며 사용한 2주의 시간을 의미 없이 버릴 수는 없자나...'
이 부분...
뜨끔합니다-ㅎ
조금이라도 새로운 분야를 하게 되면, 언제나 헤메는 것 보면
언제쯤이면 좀 잘 할 수 있을까 하는 생각이 듭니다.
그나저나 heestory님의 열정이 참 좋아 보입니다.
직접 구현하시는 분들을 만나면 참 반갑습니다.
플래너를 만드셨다면 여기서 시도한 것의 몇 배 난이도에 해당할 것 같네요.
역시 예상대로 스피닉스님은 실력파인 것 같네요.
사실 이런걸 몸과 맘으로 느끼면서도 개선하지 못하는 자신에게..
힘든 나날이내요..
근데, 개선하지 못하는 이유가 뭘까요?
시간인가요? 열정인가요? 아니면 또 다른 이유 때문일까요?
궁금하네요~
흐흣.
잘 읽었습니다.
유사한 이야기를 더 들려드려야겠군요. 하하
저는 uhihi님이 션님하고 비슷한 일을 하실거라 생각해서 그런지
프로그램 이야기를 이해하시는 것 보고 여전히 깜짝 깜짝 놀란답니다.
'parser를 작성하며 사용한 2주의 시간을 의미 없이 버릴 수는 없자나...'
이 부분...
뜨끔합니다-ㅎ (2)
그렇다면 parser를 작성하셨다는 이야기 같은데,
zzugg님은 어떤 방식으로 작성하시는지 여쭈어봐도 될까요?
일하거나, 살면서 제일 힘든 것이 마무리 점 (period)를 찍는 일인 것 같아요.
언제쯤이면 잘할 수 있을지… 게다가 이 module은 여전히 헤메며 진행중 이랍니다.
다시 읽어보니 시험하는 방법이군요.
으으음 그러네요.
일반적으로 unit test를 사용하기 때문에, 시험 코드는 자동으로 동작하거든요.
현재 시간을 보고 30초 전으로 변경하고 시험하는 방식으로 하면 될 것 같기는 하네요.
근데 integration시험에서는 사용하기 힘들 것 같아요.
시간이라는 것이 전체 시스템의 근간인 경우가 많다 보니,
시간을 변경해 버리면 정상적인 시험이라고 할 수 있을까 고민해봐야 겠네요.
어쨌든 신선한 조언 감사 드립니다.
역시, 하나 보다는 둘이 낫네요.
고맙습니다. dhyi123님
그리고 어떤 제품을 개발중이신지는 모르지만..
절대, never. 알람은 쉬운 어플이 아닙니다.
이건 경험담입니다. ㅡㅜ
글이 쉽다고 이야기 해주시니 기분이 좋네요.
그나저나 알람이 쉬운게 아니었군요.
말씀에 조금 위안이 되기도 하고,
한편으로는 이 정도면 쉬운 것 같다는 생각에,
혹시 제가 뭔가 빼먹은 거 아닌가? 하고 불안해 지는데요.
예전에 DB에 들어가는 datetime 모듈을 Oracle 스펙에 준하게 만들게 되었습니다. 이거 정말 사람잡는 일이더군요. 기본 기능 구현보다는 대부분이 예외 처리이고, 그나마 사람이 편하게 쓰고자하는 기능에 대한 지원때문에 스펙이 점점 커지는 겁니다. 더 심각한 건, 다른 사람들은 datetime 모듈이 왜 어려운지 왜 점점 일정이 길어지는지 이해를 못하는 거였습니다. 버그는 속출하고 참으로 답답했습니다.
Oracle 수준의 datetime module을 작성하셨다면 정말 재미있는 경험이었을 것 같네요.
저희도 얼마 전부터 memory-based DB를 만들어 사용하고 있는데,
조만간 datetime 부분을 추가해야 할 것 같은데, Terzeron말씀을 들어보니
기간을 넉넉하게 잡아야겠네요. 고맙습니다.
인터넷에서 찾아보시면 timefake library가 이미 만들어져서 공개된 것도 있을 겁니다.
OS는 Solaris (HP-UX), Linux, Windows상에서 개발을 하고 있습니다.
그렇다 보니, 일반적으로 H/W 혹은 OS Independent Layer를 한번 깔고 시작하기 때문에 이 정도 emulation에 큰 문제는 없을 것 같습니다.
Terzeron님께는 나중에 정말 어려운 것들은 한번 여쭈어 보고 싶은 생각이 드네요.
고맙습니다.
돈이 왔다 갔다 하는 부분이라서 사실 쉽게 용기가 않나고
파헤치기 시작했을때 실패하면 어쩌지 하는 생각에 주눅이 듭니다.
거기다 펼쳐질 작업시간들을 생각하면 하고싶다는 생각은 조용히 사리지고
그러다가 내가 뭘.. 이런식의 마음이 자리잡죠..
그리곤 포기.. 이게 반복되는 사이클입니다.
용기만 내서도 될것 같지 않고.. 문제내요..
사실 이 문제는 nowsica님의 문제만이라고 보기는 힘들 것 같아요.
저도 많은 다른 팀들과 co-work을 하는데, 이런 용기를 내지 못하는
엔지니어가 10이면 9은 된다고 생각합니다.
10명 중에 하나 정도가 용기와 노력을 들여서 바로 잡으려고 하는 것 같고요.
물론 이런 시도가 실패로 돌아가는 경우도 많죠.
중요한 것은 그 실패를 허용하는 조직이나 팀에 속해 있는가가 아닐까 합니다.
우리 나라 대부분의 팀은 이러한 실패를 허용하지 않죠.
안타까운 일이지만 어쩌 겠습니까.
그 환경 내에서, 용기를 내고, 가능하면 성공을 하는 지혜를 찾아야 될 것 같아요
아주 작은 module부터 완벽하게 시도하시기면 좋을 것 같다는 생각이 듭니다.
화이팅이고요.
연구실에서도 각종 실험 모듈 구현을 하다 보면 늘 이런 문제가 발생합니다.
개발실보다는 어느 정도 통제 가능한 계획 하에 구현이 잘 진행되지만,
아무래도 남들이 생각하지 않았던 것들을 구현하는 것이다 보니,
아무도 예견하지 못한 문제가 발생하는 것이죠!!
이렇게 되면 결국 기일까지 진행하지 못한 것에 대해 머리를 싸매고 고민하다가
교수님께 가서 더 시간을 달라고 빌어야 하는 사태가 발생하는데 ---;
그런 고로, 예상하는 일이란 참 힘든 것 같습니다. 휴...
스스로에게 도망친다는 표현을 쓰시는 것 보니까 말입니다.
말씀하시는 것 보니, 적성에 맞지 않으신가 봅니다.
산업과 학교는 추구하는 것이 다르니,
아마도 학교에 더 맞으신가 보네요.
저는 거꾸로 였어요. 실무가 너무 하고 싶었죠.
치열하게 프로들하고 경쟁하고 싶었어요.
학교 공부는 재미없었고요. 하하
그래도 예상이 힘든 것은 AKI님과 여전히 공통점이네요.
사실 어렴풋이는 알고있었어요.. 그런 환경의 조직이 아니면 쉽지 않을꺼란걸..
솔직한 얘기가 듣고 싶었거든요. 위로랄까. 같은 생각을 하고 계신 분들이
계시다라는 그것.. 힘이 생기내요.. ^^
요새 그렇게 하지 못하는 것때문에.. 이정도도 못하는 내가 엔지니어가
맞나 하는 생각으로 고민을 많이 하고 있었습니다.
엔지니어로 가야할길은 아직도 멀지만 조금씩 나아가 보겠습니다.
고맙습니다. 그리고 감사합니다.
자신의 역량보다 많은 일을 맡기거나,
필요한 시간보다 부족한 시간을 주게 되면,
제대로 해내지 못합니다.
따라서, 결과물의 불만족이 자신인지 환경인지 살펴볼 필요가 있어 보입니다.
제가 보기에 nowsica님은 가능성이 있어 보입니다.
일단 자신의 부족함을 인정하는 용기가 있으니까요.
작은, 아주 작은 것부터 시도하셔서, 성공을 해나가며 자신감을 키워가면,
잘 될 수도 있을 것 같아요.
그리고...string parsing 경우에는 저정도 수준의 간단한 것이라면, 정규식을 사용하는게 좋을것 같네요. 보다 복잡해지는 수준이라면...C++ 쪽이라면 boost에 간단한 언어 정도는 파싱가능한 녀석이 있습니다. (뭐...저녀석까진 좀 거시기하죠. 문법도 첨 접하기엔 복잡하구요)