9

特定の時間にイベントをトリガーできる clojure の方法を探しています。

例: 特定のプロセスを午前 9 時 30 分に開始してから、別のプロセスをトリガーして 30 分後に実行を開始することができます。

前もって感謝します!


更新 2:

回答を削除する前にhttps://github.com/samaaron/at-atの使用も提案してくれた @arthur-ulfeoldt と @unknown-person に感謝します。ドキュメントは少し古くなっていますが、ここに私が行った方法があります。

(「overtone.at-at」を使用)

(def my-pool (mk-pool))
;=> スレッドプールを作る

(1000 ごとに #(println "I am super cool!") my-pool :initial-delay 2000)
;=> 2 秒の遅延の後、1 秒ごとに印刷機能を開始します

(停止※1)
;=> やめます

したがって、30分の間隔で正確に9時に開始するには、次のようにします。

(require '[clj-time.core :as t])
(require '[clj-time.coerce :as c])
(「overtone.at-at」を使用)

;スレッドプールを作る
(def my-pool (mk-pool))

(def 現在時刻 (t/now))

(def 現在の日付 (t/日時
                    (t/年現在時刻)
                    (t/月現在時刻)
                    (t/日現在時刻)))

(def 次の 9 時
  (if (> 9 (t/時現在時刻))
    (t/plus 現在の日付 (t/hours 9))
    (t/plus 現在の日付 (t/日 1) (t/時間 9))))

(初期遅延の定義
   (- (c/to-long 次の 9 時) (c/to-long 現在の時間))

(1800000ごと
       #(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"); }
     };

例全体

クラス BeeperControl {
    プライベート最終 ScheduledExecutorService スケジューラ =
       Executors.newScheduledThreadPool(1);

    public void beepForAnHour() {
        最終的な実行可能なビープ音 = 新しい Runnable() {
                public void run() { System.out.println("ビープ音"); }
            };
        最終的な ScheduledFuture beeperHandle =
            scheduler.scheduleAtFixedRate(ビープ音、10、10、秒);
        scheduler.schedule(new Runnable() {
                public void run() { beeperHandle.cancel(true); }
            }、60 * 60、秒);
    }
 }
4

3 に答える 3

10

私は何かが必要でした

  • システム時間の精度が高い 1 分間隔ではなく、1 秒間隔でスケジュールされたタスクを開始しました。
  • より早い間隔で開始されたタスクが、より遅い間隔で開始されたタスクと並んで存在できるように、必要な数のスレッドを生成します。

at-at、Monotony、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

私が見つけたスケジューリング用のいくつかの Clojure ライブラリを、複雑さの昇順で示します。

  • Overtone/at-at、シンプルな事前スケジューラー
  • Monotonyは、人間が直感的に理解できる方法で物事をスケジュールするスケジューラーです。
  • Java Quartz Scheduler の上に構築された強力な Clojure スケジューリング ライブラリである Quartzite
于 2012-06-28T09:08:30.157 に答える
3

java >=5.0 には、これらすべてをカバーするScheduledExecutorServiceがあります。at-atと呼ばれる clojure プロジェクトがあり、これはこれをうまくラップしています (そして、私の個人的なお気に入りのプロジェクト Overtone の 1 つです)。

この他のSOの質問が役立つ可能性がありますClojureで定期的にコードを実行する

イントロダクション より:

スケジュール メソッドは、さまざまな遅延のあるタスクを作成し、タスク オブジェクトを返します。     
 実行をキャンセルまたは確認するために使用されます。scheduleAtFixedRate と scheduleWithFixedDelay   
 メソッドは、キャンセルされるまで定期的に実行されるタスクを作成および実行します。

cron や at type サービスを正しく設定するのは思ったより難しいため、既存の実装を使用することには、独自の実装よりもいくつかの利点があります。

于 2012-06-27T20:53:21.373 に答える