일하는 방식 고민.

난 하루에 집중해서 6~8시간, 일주일에 3~4일만 일하는 게 좋을 것 같다.

딴짓하지 않고 자신을 몽땅 짜낼만큼 높은 집중력을 내면서 항상성을 유지할 수 있는 하루 최대 근무 시간은 6시간이 최대치인 것 같다. 8시간도 큰 부담은 없는데, 사람이 언제나 전력 질주하듯 집중력을 발휘할 수 있는 건 아니니 기준은 하루 6시간 집중하는 데 맞추고 좀 여유를 내고 싶은 날은 8시간 일하면 될 것 같다.

자신을 짜내듯 일하면 업무 탈진한다. 탈진했다고 퇴사해서 충전하는 건 업무 맥락, 팀웍 구축 비용이 너무 아깝다. 그러므로 평소에(?) 일하듯이 평소에 공부하고 경험하며 충전해야 한다. 나는 느리고 시간을 많이 투입해야 해서 하루에 3시간은 학습에 쓰고, 일주일에 하루 정도는 온전히 경험성 활동에 써야 하는 것 같다. 이것도 멍하니 읽고 감상하는 게 아니라 의식하고 의도한 활동으로 해야 한다. 안 그러면 남는 게 없는 것 같다.

주 중에 일과 학습에 집중해서 달리려면 그 주를 회고하고 다음 주를 계획하는 데 하루 정도는 써야 한다. 물론 노는 것도 포함해서. 그리고 온전히 쉬는 날은 최소 하루 보장하고.

이렇게 해서 먹고 살 수 있을까? 일주일에 100시간씩 일해야 성공할 기회가 생긴다고 한다. 성공하거나 시간과 자본에서 어느 정도 자유를 얻은 지인을 보면 그런 것 같다. 물론 죽도록 일해서 결국 죽거나 동력을 잃거나 실패하는 사람은 있다. 그런데 느슨하게(?) 일해서 성공한 경우는 적어도 내 주변엔 없고, 사회에 알려진 사례도 못본 것 같다.

실은 나 혼자라면 그런 삶에 곧 도달할 것 같다. 문제는 언제까지 지속할 수 있느냐이다. 1~2년이 아니라 5년, 10년, 20년 이후에도 이렇게 일해서 먹고 살 수 있을까? 자본 소득이 뒷받쳐주지 않는 현 상황에서는 낙관하지 못한다.

나 혼자가 아니라 팀이라면 장기 지속할 가능성이 클 것 같다. 한 사람이 하는 일을 두 사람이 하면 된다. 팀 복잡도가 올라가서 발생하는 누수를 감안하면 두 사람이 소화하는 것보다 한 사람이 하는 게 더 나을지도 모른다. 하지만 예측 가능한 일정과 높은 질을 꾸준하게 내려면 한 사람이 하는 일을 두 사람이 하루 6~8시간, 주 3~4일 근무하며 처리해야 가능할 것 같다. 물론 팀원의 프로 의식과 그런 문화를 지키고 발전시키려는 태도와 마음을 서로 강하게 믿어야 가능하다. 결국 누구와 함께 하느냐가 가장 중요한 문제이다.

그렇다고 같은 일을 많은 사람이 한 팀으로 모이는 건 아니다. 오히려 일을 쪼개고 쪼갠 일에 대해 온전히 위임하고 권한을 발휘하도록 하여 개개인 간 의존성을 낮춰야 한다. 팀은 다른 조직에 비해 오히려 큰데 일은 다른 조직보다 더 원자화 되어 동작하는 그런 조직을 어떻게 만들어야 할 지 아직은 잘 모르겠다.


Django 템플릿에서 VariableDoesNotExist 예외 오류 대응하기

한 줄 요약 : Django 템플릿 엔진은 템플릿 필터에 대해서 항상 조용한 실패 처리(silent failure)를 하진 않는다.


Django Template은 없는 템플릿 변수나 템플릿 변수의 속성, 키, 색인이 없어도 오류 상황을 일으키지 않고 조용히 오류 상황을 잠재운다. 일명 Silent failure 동작이다.

{{ lorem.ipsum.hello.world }}

lorem이라는 템플릿 변수가 없든 lorem 템플릿 변수는 있는데 이 객체에 ipsum이라는 키나 속성이 없다고 가정하자. 최종 템플릿 맥락이 출력(치환)이면 Django는 변수나 키, 속성이 없다는 오류 상황을 일으키지 않으며, 저 템플릿 변수 위치엔 아무것도 출력되지 않는다. 템플릿 변수를 출력(render)하거나 템플릿 태그에서 사용할 때는 이처럼 Silent failure로 동작한다.

하지만 템플릿 필터를 거치는 경우엔 VariableDoesNotExist 예외(exception)가 발생한다. 예외 이름에서 드러나듯이 템플릿 변수가 없다는 뜻이다.

예를 들어, 존재하지 않는 템플릿 변수인 not_exist_vardivisibleby 템플릿 필터에 사용하면 예외 오류가 발생한다.

{{ '1234'|divisibleby:not_exist_var }}

이에 대해 Django 공식 문서에서는 다음과 같이 설명한다.

Thus, filter functions should avoid raising exceptions if there is a reasonable fallback value to return. In case of input that represents a clear bug in a template, raising an exception may still be better than silent failure which hides the bug. ( 출처 : custom-template-tags - writing-custom-template-filter )

간단히 말해서 템플릿 필터 함수에서는 버그를 숨기는 Silent failure 보다는 예외를 일으키는 게 낫다고 한다. 실제로 Django 내장 템플릿 필터를 보면 대체물을 대신 반환해도 될 만한 경우엔 Exception 처리를 잡아내서 오류 상황을 피하지만, 그 외의 경우엔 Exception이 발생하게 냅둔다. 문제는 그 정책이 예상을 벗어나는 경우에 발생한다. 난 default 템플릿 필터에서 조용한 실패 처리를 하지 않는 상황을 만났다. default 템플릿 필터는 대개 다음과 같이 사용한다.

{{ empty_var|default:'비었수다' }}

나도 비슷하게 사용했다.

{{ apple.attr3|default:lemon.attrdict.color }}

Django 템플릿 엔진 동작에 익숙하다면 다음과 같이 동작하길 기대(예상)한다.

  1. apple.attr3가 없으면 lemon.attrdict['color']를 대신 출력
  2. lemon.attrdictcolor 키가 없으면 결국 아무것도 출력하지 않고 Silent failure.

딱히 Exception이 발생할만한 로직이 아니고, default 필터 함수를 봐도 인자 두 개 받아서 return value or arg로 동작하는 것 뿐이다. 다시 말해 default 템플릿 필터인 Python 함수는 두 개 인자를 받는데, 첫 번째 인자로 받는 | 앞에 있는 apple.attr3가 있으면 해당 객체를 반환하고, 없으면 두 번째 인자로 받는 : 뒤에 있는 lemon.attrdict.color를 반환한다.

하지만 실제로는 VariableDoesNotExist 예외 오류가 발생한다. 이 예외는 with 템플릿 태그로 해결하면 된다.

with 템플릿 태그로 VariableDoesNotExist 예방

with 템플릿 태그는 Silent failure 처리를 해주니 with 템플릿 태그로 만든 임시 템플릿 변수인 colour엔 출력할(render) 게 없는 빈 객체가 할당이 된다. with 템플릿 태그를 안 쓴 경우엔 Silent failure를 해주는 놈이 없다보니 Exception이 그대로 나버린 것이다. 이 문제가 까다로운 이유는 Django 디버깅 화면에서는 문제가 있는 템플릿 줄(line)을 가리키지 않고 Exception이 발생한 Django 소스를 보여주는 데 있다. 평범한 속성명이나 키 이름을 쓰다가는 고생하기 십상이다.

흔히 겪는 상황은 아닐 것 같다. 나는 모델에 JSONField를 썼고, 이 모델필드의 dict 객체에 특정 키(위 예제 기준으로는 colour키)가 없어서 발생한 거였다. 뷰 함수에서 넘겨주는 템플릿 변수 이름대로라면 금방 발견했을 것 같다.

삼천포 요약 : 변수 네이밍을 괴랄하게 하면 디버깅에 도움이 된다.