Выполнение кода через регулярные промежутки времени в Clojure

Как лучше всего заставить код запускаться через равные промежутки времени в Clojure? В настоящее время я использую java.util.concurrent.ScheduledExecutorService, но это Java - есть ли способ Clojure для планирования кода для запуска через равные промежутки времени, после задержки, с возможностью отмены? Все примеры кода Clojure, которые я видел, используют Thread/sleep, что также кажется слишком Java.


person Hendekagon    schedule 22.11.2011    source источник


Ответы (4)


Стоит посмотреть исходный код Overtone, в частности код для планирования событий в определенное время.

Это система синтеза музыки, поэтому вы должны надеяться, что у них правильный временной код!

Также они услужливо выделили временной код в отдельный проект (overtone/at-at), поэтому что вы можете легко импортировать его, если хотите. Это обеспечивает удобную оболочку Clojure для базовых библиотек Java (например, ScheduledThreadPoolExecutor и другие). Синтаксис такой:

;; run some-function every 500ms
(every 500 some-function)

Вы также можете запланировать события на определенное время:

;; run some-other-function 10 seconds from now
(at (+ 10000 (now)) some-other-function)
person mikera    schedule 22.11.2011
comment
Возможно, великие умы думают одинаково :-) Если у вас есть хорошие дополнения, то внесите свой вклад в обертон/ат-ат, было бы здорово, если бы мы могли разработать единую отличную библиотеку синхронизации в Clojure! - person mikera; 22.11.2011
comment
хм, не совсем... те же имена функций, но другой подход. мой зависит от clj-time... at-at выглядит хорошо - спасибо! - person Hendekagon; 22.11.2011
comment
хотя это не совсем то, что мне нужно, так как мне также нужно, чтобы дела делались в определенное время в определенные дни - person Hendekagon; 22.11.2011
comment
Отличный ответ, я думал о том, чтобы потребовать что-то подобное в одном из моих проектов, обязательно посмотрю overtone/at-at! - person djhworld; 25.11.2011
comment
overtone/at-at в последние месяцы немного пренебрегали, эта вилка может быть интересной: github.com/silasdavis/ в-в - person berdario; 09.05.2014

На веб-сайте clojure http://clojure.org/concurrent_programming:

Во всех случаях Clojure не заменяет систему потоков Java, а работает с ней. Функции Clojure являются java.util.concurrent.Callable, поэтому они работают с инфраструктурой Executor и т. д.

Похоже, вы уже делаете это правильно.

(import 'java.util.concurrent.Executors)
(import 'java.util.concurrent.TimeUnit) 
(.scheduleAtFixedRate (Executors/newScheduledThreadPool 1) 
  #(println "Hello") 0 5 TimeUnit/SECONDS)
person nickmbailey    schedule 22.11.2011
comment
хорошо, но глупо лезть в Java, чтобы сделать что-то настолько обычное! - person Hendekagon; 22.11.2011
comment
Один из принципов Clojure — использование хост-платформы (где она достаточно мощная). В этом случае ответ clojure вряд ли будет меньше одного выражения. - person Arthur Ulfeldt; 22.11.2011
comment
interop великолепен, и, конечно, использование Java имеет смысл для этого, но я бы, по крайней мере, ожидал обертку из эстетических соображений. - person Hendekagon; 22.11.2011
comment
ИМХО здесь Java недостаточно мощен: ScheduledExecutorService имеет 3 (4) метода, и только один из них перегружен, чтобы принимать Callable вместо Runnable, с неожиданным результатом, что исключения в вашей запланированной функции будут молча проглочены (даже не печатая ничего в stderr !)... Очевидно, меня не очень волнует результат повторяющейся запланированной функции, поэтому мне не нужен целый Callable... Я посмотрел на at-at и, к сожалению, кажется, что он не переносится его аргумент fn в try-catch-printstacktrace либо - person berdario; 09.05.2014

Я ответил на свой вопрос @ Реализация планировщика типа cron в clojure< /а>

может быть, cronj может помочь?

person zcaudate    schedule 28.07.2012

Библиотека tools.timer — это оболочка таймера Java: https://github.com/Ruiyun/tools.timer

Он очень прост в использовании:

(use 'ruiyun.tools.timer)
(run-task! #(println "Say hello every 5 seconds.") :period 5000)
person Dmitry    schedule 25.12.2014