EasyJudge: 코드 채점용 크롬 익스텐션 개발기
크롬을 사용하는 사람이라면, 누구든 크롬 익스텐션은 하나씩 가지고 있을겁니다. 이런 익스텐션은 어떻게 개발이 되는걸까요? 그리고 익스텐션을 이용해서 실생활에 불편했던 점을 해결할 수 있지 않을까요? 이번 포스트에서는 제가 개발한 익스텐션을 예를 들며 크롬 익스텐션 개발 과정을 소개하겠습니다.
1. 전개
저는 이번 학기에 자료구조 TA1를 맡게 되었습니다. 자료구조를 실습하며 과제로 제출한 코드를 제가 직접 채점을 해야하는데, 정말 귀찮은 작업입니다.
- 코드를 다운로드 받는다.
- 다운로드 받은 코드를 연다.
- 코드를 컴파일 & 실행한다.
- 문제에 해당하는 테스트케이스를 입력한다.
- 결과를 유심히 본다.
- 실행 결과에 따라 감점을 하거나 넘어간다
- 위 행동을 반복한다.
위 사진처럼 파일도 엄청 많이 생기고, 특히 파일 입출력이 문제에 포함된다면 그것대로 더 귀찮아집니다. 입력용 파일을 새로 만들어 주고, 출력용 파일도 확인해야 돼서 일이 2배는 더 생깁니다.
그래서 저는 자동 채점 프로그램을 만들기로 결심하고 어떤 플랫폼에서 만들지를 고민하다, 저는 크롬 익스텐션으로 만들기로 했습니다. 이유는 다음과 같습니다.
- 채점할 코드를 다운로드 하지 않고, 채점하기 위해서는 서버에 저장된 데이터를 받아와야 하는데, 브라우저에서 불러오는게 적합해 보여서
- 채점 중, 다른 프로그램으로 전환하지 않고, 온전히 브라우저 내에서 채점을 하는것이 편리해서
- 크롬 익스텐션이 어떻게 동작하는지 궁금해서
그렇게 저의 크롬 익스텐션 개발기는 시작되었습니다.
2. 프로젝트 구조
EasyJudge는 크게 2가지로 나뉩니다. 코드를 받아오고 실행 결과를 알려주는 크롬 익스텐션과 코드를 생성하고 실행하는 채점 서버입니다.
2.1. 크롬 익스텐션
크롬 익스텐션은 한개의 웹 사이트 처럼 동작합니다. 익스텐션을 클릭하면 나오는 화면팝업이 HTML 파일이며 CSS와 JS를 적용 할 수 있습니다. 또한, React와 같은 웹 프론트엔트 프레임워크 또한 익스텐션에 사용 할 수 있습니다.
그리고 팝업창이 실행되지 않더라도 백그라운드에서 동작하는 서비스 워커가 있습니다.
저는 다음과 같이 구조를 설계하여, background.js
에서 채점 서버와 통신하고, popup.js
에서 팝업창을 조작하는 방식으로 구성했습니다.
2.2. 채점 서버
채점 서버는 파이썬 백엔드 프레임워크인 Flask를 사용했습니다. 사용한 이유는 그 당시 가장 친숙했고 사용하기 편리했던 프레임워크였기 때문입니다.
또한 subprocess
를 이용해 파일을 컴파일, 실행하여 결과를 종합했습니다.
그리고 서버 배포의 효율성과 성능을 고려하여 Docker 환경에서 동작하도록 구성했습니다.
3. 고난의 행군
개발은 매일매일이 고난의 연속이였습니다. 지식이 없는 분야인 크롬 익스텐션과 웹 서버에 대해서 공부와 동시에 개발을 하려니 제가 잘하고 있는지 의문이 들었지만, Done is Better than perfect 라는 말을 가슴에 두고 꾸준히 개발했습니다.
다음은 제가 EasyJudge를 개발하며 있었던 난관을 설명해드리겠습니다.
3.1. domController.js
저는 해당 익스텐션을 HTML/CSS와 Vanilla JavaScript를 사용했기 때문에, DOM을 직접 조작해야 합니다…
대략 15개에 대한 DOM을 작성하며 하루에 300번씩 React로 갈아탈까 고민을 했지만, React로 갈아타면 절대로 익스텐션을 완성하지 못할까봐 그냥 참고 개발했습니다.
DOM 조작 뿐만 아니라, 값을 가져 오는것에도 제 미숙한 구조 설계 덕에 아주 이상한 코드가 완성되었습니다. 이것으로 객체지향에 대한 필요성과 구조를 먼저 확립하지 않고 코딩하는 것의 위험성을 깨달았습니다.
3.2. 메모리 제한
채점 서버 개발은 아주 순조로웠습니다. 생각보다 개발 할 기능이 없었고, DOM 조작에 당한 제가 처음부터 구조를 착실하게 쌓아 나갔기 때문에, 난잡한 코드가 만들어 지진 않았지만,
보통 온라인 저지에는 시간 제한과 함께 메모리 제한을 두는 경우가 많습니다. 공간 복잡도에 대한 제약을 두거나, 너무 많은 리소스를 사용해 오버헤드가 발생할 수 있기 때문에, 채점 서버에도 메모리를 제한하고자 했습니다.
채점을 하는데에는 위에서 서술 했듯, subprocess
를 생성하여 컴파일과 실행을 하는데, 해당 subprocess
에 메모리 제약을 두면 됩니다.
하지만, 프로세스가 메모리 부족으로 종료했는지를 판별할 방법이 없습니다! 단지 Segmentation fault
런타임 에러를 발생시키고 종료됩니다2. 저는 이를 해결하고자 며칠간 해당 내용을 찾아봤지만, 메모리 사용량을 직접적으로 모니터링 해야 한다는 글 외에는 찾아 볼 수가 없었습니다. 그걸 직접 구현 하면 채점에 너무 많은 자원을 사용 할 것 같아, 그냥 런타임 에러로 남기기로 했습니다.
3.3. 크롬 익스텐션
크롬 익스텐션에서의 고난도 있었습니다. 저는 현재 사이트 내에서, 코드를 드래그 해서 선택한 코드를 채점 해주는 기능도 포함 하고 싶었습니다.
하지만 해당 기능은 사용 할 수 없었습니다. 왜냐하면 드래그 해서 선택한 문자열을 받아 올때에는 크롬이 자동으로 \n
을 지워주기 때문입니다.
물론 C가 줄바꿈이 없어도 동작하는 관대한 언어긴 하지만, 전처리문에서는 줄바꿈이 필요하고, 기타 다른 언어에서의 이식을 고려해보자면, 차라리 기능이 없어지는것이 나을것 같아 해당 기능을 제거했습니다.
또한 크롬 익스텐션을 개발 하는 중에, 환경 변수 저장이나 HTTP 통신 등의 문제가 있었으나, 크롬 익스텐션 공식 문서를 보면서 해결할 만한 일들이었습니다.
4. 마치며
해당 프로젝트의 아이디어부터 실제 개발 완료까지 대략 3주정도 소요되었습니다. 여러 고난들이 있었지만, 잘 해쳐 나가고 개발을 완료했습니다. 제가 개발한 EasyJudge는 현재 깃허브에서 이용 가능합니다!
이 글을 통해 크롬 익스텐션 개발에 흥미를 가지셨거나, 진행중인 개발에 조금이라도 도움이 되었으면 좋겠습니다. 감사합니다.