Develop Log

처음 완성한 Toy Project - 푸코의 진자

Samgim 2021. 3. 26. 16:51

처음으로 Toy Project를 완성한 기념(?)으로 기록을 남겨둔다.

 

회사에서는 여러 프로젝트를 해보았지만, Toy Project 로도 참 많은 시도를 해보았다.

하지만 번번이 끝까지 완성한 적이 없었는데, 참 여러 가지 이유로 실패했던 것 같다.

Toy Project야 완성보다도 과정이 중요하긴 하지만 완성된 무언가를 만든다는 것은 중간에 그만두는 것보다 꽤 힘들다.

그래서 완성할 수 있었던 이유가 무엇인지 스스로 돌아보고 시행착오가 무엇이었는지도 돌아보기 위해 이 글을 적어본다.

 

먼저 내가 만든 프로젝트는 "푸코의 진자"이다.

푸코의 진자는 지구가 자전한다는 증거 중 하나이다.

일반적인 단진자 운동은 x-z 단면에서만 움직이는데, 푸코의 진자는 위도에 따라서 서서히 진자가 회전한다.

나는 이 때 진자가 회전한다는 것을 보여주기 위해 x-y 단면을 위도별로 그려주는 사이트를 만드는 것이었다.

아래 링크로 확인할 수 있다.

fp.breakfolly.com/

 

FoucaultPendulum

Show Foucault Pendulum`s movement in Physics using Phoenix Framework and Elixir

fp.breakfolly.com

코드는 github 에 올려두었다.

github.com/breakfolly/foucault_pendulum

 

시작

푸코의 진자를 만들기 시작한 것은 아주 단순한 이유였다.

처음으로 엘릭서(생소하지만 프로그래밍 언어다)를 시작할 때, 집에서 토이 프로젝트를 하면서 언어를 익혀보자고 생각했었다.
그런데 처음 시작하는 언어이니 프로젝트 설정을 어떻게 하는지 정확히 모르고 있었다.
그래서 시작은 Hello World에서 한 두 발짝 더 나아간 수준밖에 나가지 못하고 있었고,
회사일이 바빠지면서 잊혀지기 시작했다….

 

언어 성숙도가 올라오고

실무에서 이것저것 해보니 당연히 숙련도가 올라갔다. 
그리고 엘릭서 언어의 특징을 더 알아보고 싶어서 다시 토이 프로젝트를 꺼내보았다. 
마침 푸코의 진자가 있었고, 프로젝트를 재정비했다. 

애초에 만든 것이 별로 없어서 쉽게 고칠 수 있었는데, 모듈도 정리하고 좀 더 프로젝트다운 뼈대를 만들기 시작했다.

엘릭서 프로젝트에서 general 하게 사용하는 모듈의 형태를 갖춰간 것도 이때였다.
테스트 코드도 있기는 했는데 너무 단순했다.
이때 종이에 이것저것 그려가면서 앞으로 어떻게 만들어갈 것인가를 고민하기 시작했다.
사실 기능은 단순했다. 백엔드에 계산 로직을 두고, 웹소켓으로 프론트에 전송만 하면 되는 거였다.
딱히 프론트에서 전송받는 값도 많지 않고, 인증도 필요 없어서 그리 할 일이 많아 보이지는 않았다.
정말 장난감이라는 의미에 딱 맞다고 생각했는데…. 이 프로젝트에서 어려운 점은 바로 계산 로직이었다.

 

 

핵심 로직을 만들다

푸코의 진자를 만든 계기는 딱히 특별한 게 아니었다.
프론트에서 보여줄 때 있어 보여서… 말고는 딱히 이유는 없었다.
마침 생각난 것이 푸코의 진자였을 뿐이었다. (소설 푸코의 진자를 읽고 난지 얼마 안 되었을 때였을 것이다.)
문제는 핵심 로직이 될 수식이었는데, 학부 수준의 물리학 지식은 있어야 했다.
복수전공으로 물리학을 하긴 했는데, 졸업한 지 어언 n 년… 기억이 날 리가 있나.
그래도 유명한 문제니까 나름대로 코드는 구글링 해보면 어딘가 있지 않을까 하고 검색을 거듭했다.
하지만 물리학도가 만든 코드는 도대체 알아볼 수가 없고 정확히 내가 원하는 것도 아니었다.

n 년 만에 역학 책을 꺼내 들고 학부 때처럼 풀기 시작했다.
그 때라면 너무 간단히 풀었을 문제인데… 책이랑 나무 위키의 수식을 참고하면서 코드에 구현할만한 수준까지 만들어내었다. 
물리학적인 답이라면 이미 풀려있는 답이 다 나와있지만, 코드로 녹아내려면 input -> output 이 매우 명확해야 했다.
어떤 값을 사용자에게 입력받을지, 무엇을 그려줄지에 따라서 수식은 아마 달라졌을 것이다.
그러려면 어떤 변수가 필요한지, 지원하는 계산 라이브러리는 있는지 등을 고민했던 것 같다.

 

수식을 얻은 후에는 www.wolframalpha.com/ 을 사용해서 실제로 시간이나 위치에 따른 답이 맞는지, 

초기값을 어떻게 넣어줄지 등을 계산했다.
그리고 테스트 코드에도 답을 검증하는 로직을 반영했다.
기준값은 진자의 주기, 위도(극지방, 적도, 그 외)로 쉽게 잡아줄 수 있었다.
하지만… 역시나 중간에 계산한 것을 코드로 잘못 구현해서 한참 삽질은 한 번 했었다. 

그래도 테스트가 모두 통과하고 계산 값을 엑셀로 그래프로 그려보면서 진자가 그려주는 모양이 맞는지도 확인했다.
모든 개발 과정이 그렇지만, 계속해서 실패하다가 의도한 대로 딱 동작하는 그 순간이 역시 짜릿했다. 

 

 

웹 프론트 개발

모듈화의 중요성

엘릭서는 Phoenix Framework를 웹 프레임워크로 사용한다.
하지만 초창기에 전혀 모르는 상태에서 모듈만 만들어버리는 바람에 Phoenix Framework를 붙이지 않고 개발했다.
‘아, 한 번 phoenix로 이식을 해야겠구나 삽질을 할 수도 있겠다.’ 하고 생각했는데 의외로 금방 해냈다.
일단 Phoenix Framework 가 매우 모듈화가 쉬워서 정말 모듈만 이식하는 수준으로도 가능했고,
가장 중요한 건 초반에 큰 꿈(?)에 부풀어서 부수적인 기능을 잔뜩 만들지 않았다는 것이었다.

예전 같으면 토이 프로젝트를 할 때, 삐까번쩍하게 한다는 욕심에 프론트부터 잔뜩 만들고 핵심 로직은 불완전하게 만들었을지도 모르겠다.
그러다가 예쁜 쓰레기(?)가 되어서 폐기 처분했을 텐데 다행히 이번에는 그러지 않았다.
프론트부터 붙였으면 아마 Phoenix 가 존재하는지도 모르고 엉뚱한 것들을 붙여서 멀리 돌아왔을 것이다.
아마 그걸 다시 떼고 붙이고 하느라 많은 시간을 소모했을지도 모르겠다.

다행히 핵심 모듈만 만들고 테스트도 더 붙여보았다.
그리고 최대한 단순하게 만들어서 딱 모듈 하나에 계산 로직을 컴팩트하게 넣어놨다.
여러 번 토이 프로젝트를 하면서 자주 망했던 이유라서 다른 것 없이 핵심 로직만 제대로 구현한 것이 주효했던 것 같다.
README 조차도 붙이지 않고 그저 코드만 구현했으니… 

(그래도 README는 처음에 붙일 걸 그랬다. 나중에 붙이려니 영 귀찮고 의욕이 없어진다.)

 

 

난관이 없지는 않았는데

그렇다고 계속해서 편안한 길만 걸은 것은 아니었다. 
아니나 다를까 뜻대로 안 되는 문제는 늘 발생한다. 이번에는 그래프를 그리다가 발생한 문제였다.
Phoenix Liveview는 js 없이도 동작하는 single page application 가 가장 이상적이다.
그런데 거기에 js를 붙여 넣으려고 했더니 문제가 발생했다.

 

three.js 나 chart.js를 붙일 때 해당 라이브러리에서는 DOM을 고치는 등의 액션이 일어난다.
그런데 Liveview에서 페이지를 새로 그리면서 이 라이브러리들이 추가로 그린 DOM을 초기화해버리는 현상이 생겼다.
처음에는 어디서 잘못됐는지를 알 수가 없어서 당황했다. 
그래프를 제대로 그렸는데도 전혀 그래프가 보이지 않거나, 멋대로 줄어들어버리거나 하는 일이 일어났기 때문이다.
침착하게 생각해보면 해결할 수 있는데도, 막상 겪어보면 당황해서 사람이 쫄아붙는다. 
덕분에 몇 시간 원인을 찾느라 삽질을 하긴 했는데, 아니나 다를까 원인을 알고 보니 해결책이 아주 멀리 있지는 않았다.
Phoenix Liveview에서 이런 경우에 사용하도록 페이지를 새로 그리는 일을 피하는 HTML attribute을 지원해줘서 다행히 무사히 해결되었다.

 

 

CI/CD를 얕잡아보다가

프론트 문제도 해결되었겠다 이제 끝이 보이는 것 같았다. 
어플리케이션도 잘 돌아가고 이제 디자인을 붙여도 되겠다 싶어서 즐겁게 붙이기도 했다.
폰트도 붙여보고 색도 조정해보고 하면서 신나게 붙이다가 이제 때가 되었다 싶어서 CI/CD를 붙여보기로 했다.
Github Action에서 이 기능들을 지원한다고 하니 한 번 붙여보기로 했다.
Github 이 친절한 가이드를 해주었고, 엘릭서 Application 도 지원해주어서 클릭 몇 번으로 CI를 붙일 수 있었다.
이제 내 프로젝트는 master 브랜치에 push 할 때마다 자동으로 테스트가 돌고 빌드되었다.

문제는 이제 CD 였는데, 일단 배포할 서버가 필요하니 AWS를 사용하기로 했다.
가장 큰 걸림돌은 내가 사내 인프라만 쓰다가 AWS를 처음 써본다는 것이었다.
AWS를 사용해본 다른 개발자의 도움을 받아서 ECR로 docker를 배포하고, ECS에 task를 만들어서 해당 이미지를 올리는 방식으로 하기로 했다.
하지만 처음 해보는 툴이 쉬울 리가 없다. AWS 용어도 너무 많고 네트워크 설정도 어떻게 해야 하는지 큰 줄기가 잡히지 않아서 삽질을 많이 했다.
단어 몇 개의 개념을 익히고 각 설정이 어떻게 연결되어 있는지를 종이에 적어가면서 되나 안되나를 여러 번 반복해야 했다.
중간에는 AWS 설정 문제도 있었고, Dockerfile을 잘못 작성했다던가 하는 문제가 있어서 스트레스를 제법 받으면서 세팅을 해야 했다.
그렇게 알고 나면 쉬웠을 세팅을 며칠을 고생해가면서 해냈고, 마침내 도메인을 사서 붙이는 것까지 성공했다.

 

게다가 Github Action 이 큰 힘이 되었다. 마이크로소프트 덕분인지 Github이 이런 기능을 추가해준 것이 무척 고마웠다.

그렇지 않았으면 어떻게 했을까 하는 생각이 아직도 든다. 

앞으로도 오픈 소스 프로젝트를 진행할 때 애용할 것 같다.

 

그럼 다음 토이 프로젝트 아이디어가 떠오르길 바라며 이 글을 마친다.

'Develop Log' 카테고리의 다른 글

Jest 와 Enzyme 으로 unit test code 짜봤다.  (0) 2017.04.23
Spark API 언어 고르기  (0) 2017.04.15
c++ 로 학교 때 과제 다시 하기  (0) 2016.10.07
아 책이 너무 어렵다아  (0) 2016.10.06
간만에 기초 공부  (0) 2016.10.02