Skip to content

Commit

Permalink
Fix schedule runner (#96)
Browse files Browse the repository at this point in the history
  • Loading branch information
pilosus committed Jul 31, 2023
1 parent acdbc14 commit fe2d401
Show file tree
Hide file tree
Showing 12 changed files with 174 additions and 107 deletions.
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@ file. This change log follows the conventions of

## [Unreleased]

## [1.1.93] - 2023-07-31

### Fixed

- Jetty server excluded from the schedule runner
- Reflection warnings fixed

### Changed

- Mount states moved to separate namespaces
- Dependencies bumped

## [1.1.86] - 2023-07-31

### Added
Expand Down Expand Up @@ -243,7 +255,8 @@ documentation website added. Project has made it to the version 1.0.0!
### Added
- Bot app MVP

[Unreleased]: https://github.com/pilosus/dienstplan/compare/1.1.86...HEAD
[Unreleased]: https://github.com/pilosus/dienstplan/compare/1.1.93...HEAD
[1.1.93]: https://github.com/pilosus/dienstplan/compare/1.0.86...1.1.93
[1.1.86]: https://github.com/pilosus/dienstplan/compare/1.0.83...1.1.86
[1.0.83]: https://github.com/pilosus/dienstplan/compare/1.0.82...1.0.83
[1.0.82]: https://github.com/pilosus/dienstplan/compare/1.0.81...1.0.82
Expand Down
12 changes: 5 additions & 7 deletions deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
com.fasterxml.jackson.core/jackson-databind {:mvn/version "2.15.2"}

;; Alerts
io.sentry/sentry-clj {:mvn/version "6.24.198"}
io.sentry/sentry-clj {:mvn/version "6.26.199"}

;; Validation
expound/expound {:mvn/version "0.9.0"}
Expand Down Expand Up @@ -77,10 +77,10 @@
{io.github.athos/clj-check {:git/tag "0.1.0" :git/sha "0ca84df"}
cloverage/cloverage {:mvn/version "1.2.4"}
jonase/eastwood {:mvn/version "1.4.0"}
io.github.weavejester/cljfmt {:git/tag "0.10.6" :git/sha "4d32002"}
io.github.weavejester/cljfmt {:git/tag "0.11.1" :git/sha "0882f99"}
io.github.cognitect-labs/test-runner {:git/tag "v0.5.1" :git/sha "dfb30dd"}
nrepl/nrepl {:mvn/version "1.0.0"}
cider/cider-nrepl {:mvn/version "0.31.0"}
cider/cider-nrepl {:mvn/version "0.32.0"}
com.bhauman/rebel-readline {:mvn/version "0.1.4"}
org.clojure/test.check {:mvn/version "1.1.1"}}}

Expand Down Expand Up @@ -149,11 +149,9 @@
;; clojure -M:dev:eastwood
:eastwood
{:main-opts ["-m"
"eastwood.lint"
;; FIXME improve reflection usage
{:exclude-linters [:reflection]}]}
"eastwood.lint"]}

;; Code formatting
;; code formatting
;; clojure -X:dev:cljfmtfix
:cljfmtfix
{:exec-fn cljfmt.tool/fix
Expand Down
32 changes: 32 additions & 0 deletions src/dienstplan/alerts.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
;; Copyright (c) Vitaly Samigullin and contributors. All rights reserved.
;;
;; This program and the accompanying materials are made available under the
;; terms of the Eclipse Public License 2.0 which is available at
;; http://www.eclipse.org/legal/epl-2.0.
;;
;; This Source Code may also be made available under the following Secondary
;; Licenses when the conditions for such availability set forth in the Eclipse
;; Public License, v. 2.0 are satisfied: GNU General Public License as published by
;; the Free Software Foundation, either version 2 of the License, or (at your
;; option) any later version, with the GNU Classpath Exception which is available
;; at https://www.gnu.org/software/classpath/license.html.
;;
;; SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0

(ns dienstplan.alerts
(:require
[dienstplan.config :refer [config]]
[mount.core :as mount :refer [defstate]]
[sentry-clj.core :as sentry]))

(defstate alerts
:start
(let [dsn (get-in config [:alerts :sentry])
debug (get-in config [:application :debug])
env (get-in config [:application :env])
app-name (get-in config [:application :name])
version (get-in config [:application :version])
release (format "%s:%s" app-name version)]
(when (not debug)
(sentry/init! dsn {:environment env :debug debug :release release})))
:stop (sentry/close!))
19 changes: 3 additions & 16 deletions src/dienstplan/commands.clj
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@
[dienstplan.db :as db]
[dienstplan.helpers :as helpers]
[dienstplan.slack :as slack]
[dienstplan.spec :as spec]
[org.pilosus.kairos :as kairos]))
[dienstplan.spec :as spec]))

;; Const

Expand Down Expand Up @@ -652,24 +651,12 @@ Caveats:
:command
some?))
crontab-ok? (or (contains? #{"delete" "list"} subcommand)
(-> crontab
kairos/parse-cron
some?))]
(helpers/cron-valid? crontab))]
(cond
(not executable-ok?) :executable
(not crontab-ok?) :crontab
:else :valid)))

(defn get-run-at
"Return java.sql.Timestamp for the next run for a given crontab string"
[crontab]
(try (-> crontab
(kairos/get-dt-seq)
first
.toInstant
java.sql.Timestamp/from)
(catch Exception _ nil)))

(defn fmt-schedule-invalid-arg
[invalid-arg]
(format "Invalid <%s> argument for `schedule` command\n\n%s"
Expand All @@ -683,7 +670,7 @@ Caveats:
query-params {:channel (get-in command-map [:context :channel])
:executable (get-in command-map [:args :executable])
:crontab crontab
:run_at (get-run-at crontab)}
:run_at (helpers/next-run-at crontab)}
{:keys [result error]}
(case (keyword (get-in command-map [:args :subcommand]))
:create (db/schedule-insert! query-params)
Expand Down
70 changes: 5 additions & 65 deletions src/dienstplan/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -16,83 +16,23 @@
(ns dienstplan.core
(:gen-class)
(:require
[bidi.bidi :as bidi]
[clojure.string :as string]
[clojure.tools.cli :refer [parse-opts]]
[dienstplan.config :refer [config]]
[dienstplan.server :as server]
[dienstplan.db :as db]
[dienstplan.endpoints :as endpoints]
[dienstplan.logging :as logging]
[dienstplan.middlewares :as middlewares]
[dienstplan.schedule :as schedule]
[mount.core :as mount :refer [defstate]]
[ring.adapter.jetty :refer [run-jetty]]
[ring.middleware.cookies :refer [wrap-cookies]]
[ring.middleware.json :refer [wrap-json-response wrap-json-params]]
[ring.middleware.keyword-params :refer [wrap-keyword-params]]
[ring.middleware.params :refer [wrap-params]]
[ring.middleware.session :refer [wrap-session]]
[sentry-clj.core :as sentry]))

(defn wrap-handler
[handler]
(fn [request]
(let [{:keys [uri] :or {uri "/"}} request
request* (bidi/match-route* endpoints/routes uri request)]
(handler request*))))

(def app-raw (wrap-handler endpoints/multi-handler))

(def wrap-params+ (comp wrap-keyword-params wrap-params))

(def app
(-> app-raw
middlewares/wrap-headers-kw
wrap-params+
wrap-json-params
wrap-session
wrap-cookies
middlewares/wrap-exception-validation
middlewares/wrap-exception-fallback
middlewares/wrap-request-id
middlewares/wrap-access-log
wrap-json-response
middlewares/wrap-raw-body))

;; System config

(defstate logs
:start (logging/override-logging))

(defstate alerts
:start
(let [dsn (get-in config [:alerts :sentry])
debug (get-in config [:application :debug])
env (get-in config [:application :env])
app-name (get-in config [:application :name])
version (get-in config [:application :version])
release (format "%s:%s" app-name version)]
(when (not debug)
(sentry/init! dsn {:environment env :debug debug :release release})))
:stop (sentry/close!))

(defstate server
:start
(let [port (get-in config [:server :port])
join? (get-in config [:server :block-thread])]
(run-jetty app {:port port :join? join?}))
:stop (.stop server))
[mount.core :as mount]))

;; CLI opts

(def run-modes #{:server :migrate :rollback})
(def run-modes #{:server :migrate :rollback :schedule})

(def cli-options
[["-m"
"--mode MODE"
"Run app in the mode specified"
:default :server
:parse-fn #(keyword (.toLowerCase %))
:parse-fn #(keyword (.toLowerCase ^String %))
:validate [#(contains? run-modes %) (format "App run modes: %s" run-modes)]]
["-h" "--help" "Print this help message"]])

Expand Down Expand Up @@ -132,7 +72,7 @@
(if exit-message
(exit (if ok? 0 1) exit-message)
(case mode
:server (mount/start)
:server (server/run nil)
:migrate (db/migrate nil)
:rollback (db/rollback nil)
:schedule (schedule/run nil)))))
10 changes: 6 additions & 4 deletions src/dienstplan/db.clj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
[cheshire.core :as json]
[clojure.string :as string]
[clojure.tools.logging :as log]
[dienstplan.alerts :refer [alerts]]
[dienstplan.config :refer [config]]
[dienstplan.helpers :as helpers]
[honey.sql :as h]
Expand All @@ -41,7 +42,7 @@
(defstate db
:start (connection/->pool HikariDataSource (:db config))
;; FIXME reflection warning
:stop (-> db ^HikariDataSource .close))
:stop (-> ^HikariDataSource db .close))

;; For REPL-driven-development
;; Assuming that you run DB with `docker compose up postgres`
Expand Down Expand Up @@ -121,7 +122,8 @@
(defn get-migration-config []
(mount/start
#'dienstplan.config/config
#'dienstplan.db/db)
#'dienstplan.db/db
#'dienstplan.alerts/alerts)
{:datastore (ragtime-jdbc/sql-database db)
:migrations (ragtime-jdbc/load-resources "migrations")})

Expand Down Expand Up @@ -276,7 +278,7 @@
(mapv #(assoc % :mention/duty (= % next-duty)) users)))

(defn rotate-users
[users]
[^clojure.lang.PersistentVector users]
(let [current-duty (first (filter #(:mention/duty %) users))]
(if (not current-duty)
users
Expand Down Expand Up @@ -375,7 +377,7 @@

(defn schedule-insert!
[params]
(jdbc/with-transaction [conn db]
(jdbc/with-transaction [^java.sql.Connection conn db]
(try (let [inserted (sql/insert! conn :schedule params)]
(log/debugf "Schedule inserted: %s" inserted)
{:result (when (-> inserted :schedule/id int?)
Expand Down
22 changes: 21 additions & 1 deletion src/dienstplan/helpers.clj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@

(ns dienstplan.helpers
"Common helper functions shared across namespaces"
(:require [clojure.string :as string]))
(:require [clojure.string :as string]
[org.pilosus.kairos :as kairos])
(:import (java.time ZonedDateTime)
(java.sql Timestamp)))

(defn now-ts-sql
"Get current timestamp in JDBC API compatible format"
Expand Down Expand Up @@ -48,3 +51,20 @@
(-> s
(string/replace #"[,!?\-\.]*$" "")
string/trim))

(defn next-run-at
"Return java.sql.Timestamp for the next run for a given crontab string"
^Timestamp [crontab]
(try (-> crontab
(kairos/get-dt-seq)
^ZonedDateTime first
.toInstant
java.sql.Timestamp/from)
(catch Exception _ nil)))

(defn cron-valid?
"Return true if crontab is valid"
[crontab]
(-> crontab
kairos/parse-cron
some?))
6 changes: 5 additions & 1 deletion src/dienstplan/logging.clj
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
(:gen-class)
(:require
[clojure.pprint]
[clojure.tools.logging :as log]))
[clojure.tools.logging :as log]
[mount.core :as mount :refer [defstate]]))

(defn ex-chain
"Build exceptions chain from original one to the root"
Expand Down Expand Up @@ -49,3 +50,6 @@
message* (str message \newline ex-out)]
(log* logger level nil message*))
(log* logger level throwable message))))))

(defstate logs
:start (override-logging))
2 changes: 1 addition & 1 deletion src/dienstplan/middlewares.clj
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
(defn string->stream
"Convert string to InputStream"
([s] (string->stream s "UTF-8"))
([s encoding]
([^String s ^String encoding]
(-> s
(.getBytes encoding)
(java.io.ByteArrayInputStream.))))
Expand Down
15 changes: 7 additions & 8 deletions src/dienstplan/schedule.clj
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,14 @@
[dienstplan.db :as db]
[dienstplan.helpers :as helpers]
[mount.core :as mount]
[next.jdbc :as jdbc]
[org.pilosus.kairos :as kairos]))
[next.jdbc :as jdbc]))

(defn- next-run-ts
"Given crontab line, return the next timestamp in JDBC compatible format"
[schedule-row]
(-> schedule-row
:schedule/crontab
(kairos/get-dt-seq)
first
.toInstant
java.sql.Timestamp/from))
(helpers/next-run-at)))

(defn- schedule-update-map
[schedule-row]
Expand All @@ -53,7 +49,7 @@
(defn process-rows
"Iterate over rows from `schedule` table, process them, return number
of processed rows"
[conn rows fn-process-command fn-update-schedule]
[^java.sql.Connection conn rows fn-process-command fn-update-schedule]
(loop [events (seq rows)
processed 0]
(if events
Expand Down Expand Up @@ -91,7 +87,10 @@
(defn run
"Schedule processing entrypoint"
[_]
(mount/start)
(mount/start
#'dienstplan.config/config
#'dienstplan.db/db
#'dienstplan.alerts/alerts)
(process-events db/schedules-get
commands/send-command-response!
db/schedule-update!))
Loading

0 comments on commit fe2d401

Please sign in to comment.