Я сворачиваю 20000 симулированных показаний приливов в один atom из 8 futures. Каждое показание выше порога ещё и дописывается в outliers.log. Сводка в порядке: :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 количество строк снова другое.
Как статистика может быть абсолютно точной, а лог нет? Мне нужна ровно одна строка на каждый выброс.