9

我正在寻找任何可以在给定时间触发事件的 clojure 方法,

例如:我希望一个特定的进程在上午 9:30 开始,然后我可以触发另一个进程在半小时后开始运行,等等。

提前致谢!


更新2:

感谢@arthur-ulfeoldt 和@unknown-person,他们还建议在删除他的答案之前使用https://github.com/samaaron/at-at 。文档有点过时,但这就是我的工作方式。

(使用'overtone.at-at)

(def my-pool (mk-pool))
;=> 创建一个线程池

(每 1000 次 #(println "I am supercool!") my-pool :initial-delay 2000)
;=> 在 2 秒延迟后每 1 秒启动一次打印功能

(停止*1)
;=> 停止它

所以要让它从 9 点开始,间隔半小时,我会这样做:

(需要'[clj-time.core :as t])
(需要'[clj-time.coerce :as c])
(使用'overtone.at-at)

;制作线程池
(def my-pool (mk-pool))

(定义当前时间(t/now))

(def 当前日期 (t/日期时间
                    (吨/年当前时间)
                    (吨/月当前时间)
                    (吨/天当前时间)))

(def next-9-oclock
  (如果(> 9(吨/小时当前时间))
    (t/plus current-date (t/hours 9))
    (t/plus current-date (t/days 1) (t/hours 9))))

(定义初始延迟
   (- (c/to-long next-9-oclock) (c/to-long current-time))

(每 180 万
       #(println "我超酷!")
       我的池
       :初始延迟
       初始延迟)

更新:

@arthur-ulfeoldt,我不知道如何将一些 java 代码翻译成 clojure。 http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ScheduledExecutorService.html

像:

final ScheduledFuture<?> beeperHandle = 
        scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);

和:

final Runnable beeper = new Runnable() {
        public void run() { System.out.println("beep"); }
     };

整个例子

蜂鸣器控制类 {
    私有最终 ScheduledExecutorService 调度程序 =
       Executors.newScheduledThreadPool(1);

    公共无效 beepForAnHour() {
        最终 Runnable 蜂鸣器 = new Runnable() {
                公共无效运行(){ System.out.println(“哔”);}
            };
        最终计划未来 beeperHandle =
            scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
        scheduler.schedule(new Runnable() {
                公共无效运行(){beeperHandle.cancel(真);}
            }, 60 * 60, 秒);
    }
 }
4

3 回答 3

10

我需要一些东西

  • 以整秒间隔开始计划任务,而不是具有高系统时间精度的整分钟间隔。
  • 将根据需要生成尽可能多的线程,以便在较早时间间隔开始的任务可以与在较晚时间间隔开始的辅助任务一起存在。

在阅读了 at-at、Montony 和 Quartzite 的一些源代码之后,我觉得它们不符合我所追求的要求(这实际上是更简单的东西),所以我编写了自己的 - cronj

用法示例。

(require '[cronj.core :as cj])

(cj/schedule-task! {:id 0   :desc 0 
              :handler #(println "job 0:" %) 
              :tab "/5 * * * * * *"}) ;; every 5 seconds
(cj/schedule-task! {:id 1   :desc 1 
              :handler #(println "job 1:" %) 
              :tab "/3 * * * * * *"}) ;; every 3 seconds

(cj/start!) 

;; wait for scheduler to do its thing ......

(cj/stop!)
于 2012-07-28T02:09:09.120 回答
3

java >=5.0 的ScheduledExecutorService涵盖了所有这些以及更多内容。有一个名为at-at的 clojure 项目很好地包装了它(并且是我个人最喜欢的项目 Overtone 的一部分)

您可能会发现这个其他 SO 问题很有帮助在 Clojure 中定期执行代码

从归纳:

schedule 方法创建具有各种延迟的任务并返回一个任务对象     
 用于取消或检查执行。scheduleAtFixedRate 和 scheduleWithFixedDelay   
 方法创建并执行定期运行直到取消的任务。

正确获取 cron 或类型服务比听起来要难,因此使用现有实现可能比滚动自己的实现具有一些优势。

于 2012-06-27T20:53:21.373 回答
3

我遇到了一些用于调度的 Clojure 库,按复杂度升序排列:

  • Overtone/at-at,一个简单的提前调度器
  • Monotony,一种以人类直观的方式安排事情的调度程序。
  • Quartzite,一个强大的 Clojure 调度库,构建在 Java Quartz Scheduler 之上。
于 2012-06-28T09:08:30.157 回答