8개의 future에서 시뮬레이션된 조수 측정값 20000개를 하나의 atom에 fold해요. 임계값을 넘는 측정값은 모두 outliers.log에도 append하고요. 요약은 문제없어요. :n은 항상 20000이고, :outliers는 seed가 고정이라 매번 똑같아요. 그런데 로그의 줄 수가 카운터보다 많아요. 지난번 실행에서는 로그가 250줄 정도였고 카운터는 그보다 조금 낮았어요. 어떤 id는 두 번씩 나와요. --workers 1로 하면 둘이 일치해요.
(defn- log-line [& parts]
(spit (:log-file config)
(str (str/join " " parts) "\n")
:append true))
(defn fold-reading [st r]
(let [lvl (:level r)]
(when (outlier? r)
(log-line "outlier" (:id r) (format "%.3f" lvl)))
(cond-> (-> st
(update :n inc)
(update :sum + lvl)
(update :sumsq + (* lvl lvl)))
(outlier? r) (update :outliers inc))))
(defn record! [r]
(swap! stats fold-reading r))
여러 스레드에서 spit :append를 하면 이중으로 쓰는 건가 싶었는데, 그러면 카운터도 틀려야 하잖아요. partition-all 청크도 확인했는데 겹치지 않아요. :n이 딱 20000이니까요. 실행 전에 로그는 매번 지워요. 같은 seed로 다시 돌려도 줄 수가 매번 달라요.
통계는 정확한데 로그만 틀릴 수 있는 이유가 뭘까요? outlier당 정확히 한 줄만 남기고 싶어요.
영어에서 번역·원문 보기I fold 20000 simulated tide readings into one atom from 8 futures. Every reading above the threshold also gets appended to outliers.log. The summary is fine: :n is always 20000, and :outliers is the same every run because the seed is fixed. But the log has more lines than the counter. Last run it was around 250 lines against a counter a little lower. Some ids appear twice. With --workers 1 they agree.
(defn- log-line [& parts]
(spit (:log-file config)
(str (str/join " " parts) "\n")
:append true))
(defn fold-reading [st r]
(let [lvl (:level r)]
(when (outlier? r)
(log-line "outlier" (:id r) (format "%.3f" lvl)))
(cond-> (-> st
(update :n inc)
(update :sum + lvl)
(update :sumsq + (* lvl lvl)))
(outlier? r) (update :outliers inc))))
(defn record! [r]
(swap! stats fold-reading r))
I thought spit :append from many threads double-writes, but then the counter would be wrong too. I also checked the partition-all chunks and they don't overlap, since :n is exactly 20000. I delete the log before each run. The line count is different again on the next run with the same seed.
How can the stats be exactly right while the log is not? I want exactly one line per outlier.