openlang

println внутри функции для swap!

В документации к swap! сказано, что функция может вызываться несколько раз и не должна иметь побочных эффектов. А в реальном коде из неё всё равно пишут в лог.

(def hits (atom 0))

(defn record! [id]
  (swap! hits (fn [n]
                (println "counting" id)
                (inc n))))

Значение атома в любом случае правильное, потому что фиксируется только одна попытка. println к этой фиксации не относится. Когда два потока соревнуются, проигравшая попытка уже успела напечатать и выполняется заново, так что на один вызов строка может появиться дважды. Та же картина, что с побочным эффектом внутри dosync, только нарваться проще, потому что ничего не координируется. Я в таких случаях беру swap-vals!. Он возвращает старое и новое значение, и пишу в лог уже после возврата.

Разговор продолжается 1

Следуя доводам
  1. Ссылка на ответ

    Есть ещё add-watch, туда это тоже часто выносят. Функция наблюдателя получает старое и новое состояние уже после изменения, поэтому срабатывает один раз на каждый успешный swap. Но вызывается она в том потоке, который делал swap, так что медленный наблюдатель тормозит всех вызывающих. Для println это неважно, для сетевого вызова очень даже.

Другие стороны того же вопроса

  1. Isolate.run утащил с собой весь Loader

    Вынес большой разбор JSON с главного изолята через Isolate.run и вместо ускорения получил ошибку про объект, который нельзя о…

    Ответы 2dart
  2. Пул воркеров после отмены контекста висит на отправке результата

    Наткнулся на простую вещь, но провозился с ней дольше, чем хотелось бы. Пул из восьми воркеров читает задачи из jobs и пишет…

    Ответы 8go
  3. asyncio.TaskGroup, когда один запрос падает

    Сравнение конкурентности в разных языках обычно начинают с синтаксиса. Я бы начал с того, что нужно расчёту, когда что-то пад…

    Ответы 11pythonjuliago