본문 바로가기
C.W.K.
Stream
Lesson 02 of 04 · published

조용한 일일 Loop

~10 min · scheduling, backups, unattended, honest-failure

Level 0Open Gate
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"하루에 한 번, 아무도 깨지 않은 시간에 stronghold 는 스스로의 정직한 스냅샷을 뜨고 새 백업을 철해 둬. 못 한 날엔 못 했다고 말해. 조용히."

06:31 에 도는 것들

매일 아침 06:31 Asia/Seoul, 단일 프로세스가 일일 loop 를 돌려. 한 번의 순회에서 이만큼을 해. strict-primary 로 quote 와 FX 를 refresh 하고(fallback 없음, Track 4 의 무인 경로 그대로), Markdown export 둘을 다시 만들고, writable owner 마다 portfolio_value_history row 를 하나씩 추가해서 스냅샷에 시간축을 이어 붙이고, SQLite-consistent 백업을 순환시키며 최신 14개를 유지해. live 스냅샷 시스템에 날짜 붙은 durable 이력과 최근 백업이라는 안전망을 달아 주는 심장박동이야. 사람 손 하나 안 닿고.

strict-primary 인 이유, 아무도 안 보고 있으니까

이 refresh 가 strict-primary 라는 점을 봐. primary provider 만 쓰고 fallback 은 안 해. provider-boundaries 트랙에서 배운 무인 규칙이 제집을 찾은 모습이지. 06:31 엔 provider 교체를 확인해 줄 사람이 없으니 loop 는 교체 자체를 거부해. 깨끗한 primary 데이터를 얻거나, 정직한 실패를 기록하거나 둘 중 하나야. 일일 스냅샷은 durable 하고 canonical 한 기록이잖아. 제일 피하고 싶은 건 몰래 갈아탄 fallback 출처가 아무도 모르는 채로 영구 기록에 박히는 거야.

무인 작업은 정직하게 실패해야 해. 조용히 실패하거나 성공을 꾸며내면 안 되고. 지켜보는 사람이 없는 예약 job 은 덜이 아니라 더 보수적이어야 해. 확인을 요청할 수 없으니 확인이 필요한 일은 거부해야 하고, 못 해낸 일은 덮는 대신 기록해야 해. 지켜보는 눈이 없다는 사실은 정직함의 기준을 낮추는 게 아니라 오히려 끌어올려.

실패는 크래시가 아니라 눈에 보이는 chip 이 돼

loop 가 일을 끝내지 못하면, 그러니까 provider 가 죽었거나 네트워크가 끊겼으면, 프로세스를 무너뜨리지도 조용히 건너뛰지도 않아. 실패를 ok:false 마커와 상세 내용으로 정직하게 기록하고, 그게 UI 에 stale chip 으로 떠올라. 마지막 refresh 가 실패했고 지금 보는 데이터가 원래보다 오래됐다는, 차분하지만 분명한 표시야. 기존 observation 은 고스란히 남고 아무것도 부서지지 않아. Keep 가 다른 모든 낡음을 다루는 방식 그대로, low-trigger 로 라벨을 달아 진실을 알려 주는 거야. 이건 낡았고, refresh 는 실패했다고.

crash-safe 백업은 loop 가 들어 둔 조용한 보험이야. 쓰기 도중이 아닌 시점에 뜬 SQLite-consistent 백업을 순환시키며 최신 14개를 유지한다는 건, 가족 기록의 복원 가능한 최근 사본이 언제나 있다는 뜻이야. Track 1 의 forward-only 복구와 합치면 재해 대응 이야기가 완성돼. 좋은 백업을 복원하고, 좋은 리비전을 고르고, 프로세스 하나를 재시작한다. 그 안전망을 매일 새로 짜 두는 게 일일 loop 야.

Code

일일 loop: refresh 하고, 기록하고, 백업한다. 정직하게 (예시)·python
def daily_loop():                  # 06:31 Asia/Seoul, in-process
    try:
        refresh_quotes(strict_primary=True)   # fallback 없음 (무인이니까)
        refresh_fx(strict_primary=True)
        regenerate_markdown_exports()
        for owner in writable_owners():
            append_value_history(owner, today())  # 시간축이 자라남
        rotate_backups(keep=14)                   # crash-safe 스냅샷
        set_setting("last_daily_refresh", {"ok": True, "at": now()})
    except Exception as e:
        # 크래시하지 않고, 성공을 꾸미지도 않아. 정직하게 기록해.
        set_setting("last_daily_refresh", {"ok": False, "error": str(e)})
        # UI 가 이 기록을 읽고 차분한 'stale' chip 을 띄워. 데이터는 무사해.

External links

Exercise

어떤 시스템이든 좋으니 무인 일일 job 을 하나 설계해 봐. 백업이든 sync 든 리포트든. 세 가지를 정하는 거야. 순조로울 때 뭘 하는지, 확인해 줄 사람이 없어서 뭘 거부하는지, 크래시하지도 성공을 꾸미지도 않으면서 실패를 어떻게 기록해 사람이 나중에 알게 할지. 그다음 그 실패가 화면에 어떻게 떠야 하는지 정해 봐. 요란한 알림일까, 차분한 표시일까? 시스템의 기질에 비춰 선택을 정당화해 봐.
Hint
예약 job 의 함정은 둘이야. 조용한 실패는 깨진 걸 아무도 모르게 하고, 꾸며낸 성공은 틀린 걸 쓰고 태연히 넘어가. 정직한 중간 지점은 기록된 ok:false 야. 나중에 화면이 읽어서 보여줄 수 있는 기록. 차분한 도구라면 보이는 stale 표시가 알람보다 나아. 다만 타협할 수 없는 건 하나야. 진실이 사람 눈에 띌 곳에 반드시 기록된다는 것.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.