Created
August 23, 2019 14:26
-
-
Save ivarref/02384ac213694c13d4f4b024602bd4b8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (ns ivarref.recurring-cup | |
| (:require [tea-time.core :as tt] | |
| [tea-time.virtual :as tv]) | |
| (:import (java.time ZonedDateTime ZoneId Instant DayOfWeek) | |
| (java.time.format DateTimeFormatter) | |
| (tea_time.core Task))) | |
| ;; Example of how to add scheduling of functions returning ZonedDateTime | |
| ;; and lazy sequences returning ZonedDateTime to aphyr/tea-time | |
| (defn ^ZonedDateTime now-tz [tz] | |
| (ZonedDateTime/ofInstant | |
| (Instant/ofEpochSecond (tt/unix-time)) | |
| (ZoneId/of tz))) | |
| (defn ^ZonedDateTime now-utc [] | |
| (now-tz "UTC")) | |
| (defn daily | |
| [{:keys [hour minute timezone] | |
| :or {hour 0 | |
| minute 0 | |
| timezone "UTC"}}] | |
| (fn | |
| ([] | |
| (-> (now-tz timezone) | |
| (.withNano 0) | |
| (.withSecond 0) | |
| (.withMinute minute) | |
| (.withHour hour) | |
| (#(if (or (.isEqual % (now-utc)) (.isAfter % (now-utc))) | |
| % | |
| (.plusDays % 1))))) | |
| ([prev-value] | |
| (.plusDays prev-value 1)))) | |
| (defn hourly | |
| [{:keys [minute timezone] | |
| :or {minute 0 | |
| timezone "UTC"}}] | |
| (fn | |
| ([] | |
| (-> (now-tz timezone) | |
| (.withNano 0) | |
| (.withSecond 0) | |
| (.withMinute minute) | |
| (#(if (or (.isEqual % (now-utc)) (.isAfter % (now-utc))) | |
| % | |
| (.plusHours % 1))))) | |
| ([prev-value] | |
| (.plusHours prev-value 1)))) | |
| (defn to-seq | |
| ([f] (to-seq (f) f)) | |
| ([v f] (lazy-seq (cons v (to-seq (f v) f))))) | |
| (defn zoned-date-time->linear-micros [^ZonedDateTime zdt] | |
| (tt/unix-micros->linear-micros (tt/seconds->micros (.toEpochSecond zdt)))) | |
| (defrecord ZonedDateTimeFnTask [id f ^long t prev-time next-time-fn cancelled] | |
| Task | |
| (succ [this] (when-not @cancelled | |
| (when-let [next-time (next-time-fn prev-time)] | |
| (assoc this :t (zoned-date-time->linear-micros next-time) | |
| :prev-time next-time)))) | |
| (run [this] (when-not @cancelled | |
| (f))) | |
| (cancel! [this] | |
| (reset! cancelled true))) | |
| (defn at-zdt-fn! | |
| [zdt-fn f] | |
| (let [first-time (zdt-fn)] | |
| (tt/schedule! (ZonedDateTimeFnTask. | |
| (tt/task-id) | |
| f | |
| (zoned-date-time->linear-micros first-time) | |
| first-time | |
| zdt-fn | |
| (atom false))))) | |
| (defn seq->fn! [s] | |
| (let [state (atom s)] | |
| (fn [& args] | |
| (let [[head & tail] @state] | |
| (reset! state tail) | |
| head)))) | |
| (defn at-seq-fn! | |
| [sq f] | |
| (let [first-time (first sq)] | |
| (tt/schedule! (ZonedDateTimeFnTask. | |
| (tt/task-id) | |
| f | |
| (zoned-date-time->linear-micros first-time) | |
| first-time | |
| (seq->fn! (rest sq)) | |
| (atom false))))) | |
| (defn now-println [& args] | |
| (apply (partial println (.format (now-tz "Europe/Oslo") (DateTimeFormatter/ofPattern "E HH:mm"))) | |
| args)) | |
| (defn utc-println [& args] | |
| (apply (partial println (.format (now-utc) (DateTimeFormatter/ofPattern "E HH:mm"))) | |
| args)) | |
| (comment | |
| (->> (to-seq (daily {:hour 9 :minute 45 :timezone "Europe/Oslo"})) | |
| (remove (comp #{DayOfWeek/SATURDAY DayOfWeek/SUNDAY} #(.getDayOfWeek %))) | |
| (take 5) | |
| (mapv #(.format % (DateTimeFormatter/ofPattern "E HH:mm"))))) | |
| (comment | |
| (do | |
| (tt/stop!) | |
| (tv/reset-time!) | |
| (tv/with-virtual-time! | |
| (while (not= DayOfWeek/MONDAY (.getDayOfWeek (now-utc))) | |
| (tv/advance! (+ (tt/unix-time) (* 24 3600)))) | |
| (at-seq-fn! (->> (to-seq (daily {:hour 9 :minute 45 :timezone "Europe/Oslo"})) | |
| (remove (comp #{DayOfWeek/SATURDAY DayOfWeek/SUNDAY} #(.getDayOfWeek %)))) | |
| (fn [] (now-println "Get first cup of ☕"))) | |
| (tv/advance! (+ (tt/unix-time) (* 7 24 3600)))))) | |
| (comment | |
| (do | |
| (tt/stop!) | |
| (tv/reset-time!) | |
| (tv/with-virtual-time! | |
| (tv/advance! (* 9 3600)) | |
| (at-zdt-fn! (hourly {:minute 45 :timezone "UTC"}) | |
| (fn [] (utc-println "Get another cup of ☕ \uD83D\uDE80\uD83D\uDE80\uD83D\uDE80"))) | |
| (tv/advance! (+ (tt/unix-time) (* 3 3600)))))) | |
| (comment | |
| (do | |
| (tt/stop!) | |
| (tv/reset-time!) | |
| (tv/with-virtual-time! | |
| (at-zdt-fn! (daily {:hour 9 :minute 45 :timezone "Europe/Oslo"}) | |
| (fn [] (now-println "Get first cup of ☕ \uD83D\uDE80"))) | |
| (tv/advance! (* 7 24 3600))))) | |
| ;(println "it's now:" (.format (now-tz "Europe/Oslo") (DateTimeFormatter/ofPattern "HH:mm:ss.SSS"))) | |
| ;((daily {:hour 2 :timezone "Europe/Oslo"}))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment