Giter Site home page Giter Site logo

quartzite's Introduction

Quartzite, a thin Clojure layer on top the Quartz Scheduler

Quartzite is a powerful Clojure scheduling library built on top the Quartz Scheduler.

Project goals

  • Support all commonly used Quartz features but follow the 80/20 rule
  • Be (reasonably) idiomatic but easy to understand for people familiar with Quartz
  • Be well documented
  • Be well tested
  • Integrate with libraries like JodaTime where appropriate, like Monger, a modern Clojure MongoDB client does
  • Not a half-assed effort: libraries should be well maintained and test-driven or not be open sourced in the first place

Project Maturity

Quartzite is past 2.0. We consider it to be stable and reasonably mature. Quartz Scheduler is a very mature project.

API changes generally follow semantic versioning and are driven by the user feedback.

Supported Clojure Versions

Quartzite requires Clojure 1.6 or later. The most recent release is always recommended.

Maven Artifacts

The Most Recent Release

Quartzite artifacts are released to Clojars. If you are using Maven, add the following repository definition to your pom.xml:

<repository>
  <id>clojars.org</id>
  <url>http://clojars.org/repo</url>
</repository>

The Most Recent Version

With Leiningen:

Clojars Project

With Maven:

<dependency>
  <groupId>clojurewerkz</groupId>
  <artifactId>quartzite</artifactId>
  <version>2.1.0</version>
</dependency>

Getting Started, Documentation

Please refer to the Getting Started with Clojure and Quartz. Quartzite documentation guides are not fully complete but cover most of the functionality.

Quality Clojure documentation is available elsewhere.

Community

Quartzite has a mailing list. Feel free to join it and ask any questions you may have.

To subscribe for announcements of releases, important changes and so on, please follow @ClojureWerkz on Twitter.

Quartzite Is a ClojureWerkz Project

Quartzite is part of the group of Clojure libraries known as ClojureWerkz.

Continuous Integration

Continuous Integration status

CI is hosted by travis-ci.org

Development

Quartzite uses Leiningen 2. Make sure you have it installed and then run tests against all supported Clojure versions using

lein all test

Then create a branch and make your changes on it. Once you are done with your changes and all tests pass, submit a pull request on Github.

License

Copyright (C) 2011-2023 Michael S. Klishin, Alex Petrov, the ClojureWerkz team and contributors.

Distributed under the Eclipse Public License, the same as Clojure.

quartzite's People

Contributors

adamwynne avatar alvarogarcia7 avatar ben-biddington avatar bitdeli-chef avatar bronsa avatar dlebrero avatar ifesdjeen avatar iperdomo avatar michaelklishin avatar nbeloglazov avatar piranha avatar pwojnowski avatar ryfow avatar songsd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

quartzite's Issues

to-job-data converts records to maps

clojurewerkz.quartzite.conversion/to-job-data converts records to maps.
Example:

(require '[clojurewerkz.quartzite.conversion :as c])

(defrecord Abc [a b c])

(def initial {"record" (->Abc :a :b :c)})
(type (initial "record")) ; user.Abc

(def converted (-> initial c/to-job-data c/from-job-data))
(type (converted "record")) ; clojure.lang.PersistentArrayMap

The problem is that to-job-data uses stringify-keys to convert map to JobDataMap-compatible map. And stringify-keys converts records to maps too. I would expect to-job-data actually convert keys to maps only on first level and don't go recursively. Or maybe don't do implicit conversion and validate map to have only string keys.

Unable to schedule one job with multiple triggers

Hi.

I'd like to do something like this:

(defjob NoOpJob
  [ctx]
  (println "Does nothing"))


(defn -main
  [& m]
  (qs/initialize)
  (qs/start)
  (let [job1 (j/build
              (j/of-type NoOpJob)
              (j/with-identity (j/key "jobs.noop.1")))
        tk1      (t/key "triggers.1" "triggs1")
        tk2      (t/key "triggers.2" "triggs2")
        trigger1 (t/build
                  (t/with-identity tk1)
                  (t/start-now)
                  (t/with-schedule (schedule
                                     (with-repeat-count 10)
                                     (with-interval-in-milliseconds 2000)
                                    )))
        trigger2 (t/build
                  (t/with-identity tk2)
                  (t/start-now)
                  (t/with-schedule (schedule
                                     (with-repeat-count 16)
                                     (with-interval-in-milliseconds 1000)

                                    )))
        ]
  (qs/schedule job1 trigger1)
  (qs/schedule job1 trigger2)    ;;;This causes error
    ))

but I am getting error:

"
ObjectAlreadyExistsException Unable to store Job : 'DEFAULT.jobs.noop.1', because one already exists with this identification. org.quartz.simpl.RAMJobStore.storeJob (RAMJobStore.java:277)
"

Example here suggests it should be possible:
http://www.mkyong.com/java/example-to-run-multiple-jobs-in-quartz/

For now I'm like to fully duplicate the job to schedule 2, independent instances of the same workload.

Kind regards.

Ludwik.

Testing: How to execute a job without scheduling?

How do I execute a job without scheduling it? Is there now way to run the execute method on a given Job definition so that I can test against my defjob definitions?

E.g.

(defjob AJob [ctx]
  (do-stuff-with ctx))

(. execute (AJob.) {:some-context 1})

From reading the tests, it seems like I have to go through the scheduler :/

Include job-executing?

Hi,
I would like to contribute two helper functions to the scheduler api, but i'm not sure if the're generic enough for public consumption, what do you think?

(defn- get-executing-jobs-by-key [key]
  "Get a list of executing jobs by key (usually returns just 1 job)"
  (filter #(= (.. ^JobExecutionContext % (getJobDetail) (getKey)) (jobs/key key))
          (.getCurrentlyExecutingJobs ^Scheduler @scheduler/*scheduler*)))

(defn job-executing? [key]
  "Returns true if there is a running job for that particular key"
  (if (seq (get-executing-jobs-by-key key)) true false))

Thanks,

How to configure quartz clustering?

I write the config file in lein resources dir named quartz.properties. And the content of the file is:

#============================================================================
# Configure Main Scheduler Properties
#============================================================================

org.quartz.scheduler.instanceName = MyClusteredScheduler
org.quartz.scheduler.instanceId = AUTO


#==============================================================
#Configure JobStore
#==============================================================
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 200


#============================================================================
# Configure Datasources
#============================================================================

org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL = jdbc:mysql://127.0.0.1:3306/quartz?characterEncoding=UTF-8
org.quartz.dataSource.myDS.user = demo
org.quartz.dataSource.myDS.password = demo
org.quartz.dataSource.myDS.maxConnections = 5
#org.quartz.dataSource.myDS.validationQuery=select 0 from dual

#==============================================================
#Configure ThreadPool
#==============================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true

And I wrote the Clojure code like the demo said:


(defmacro def-stateful-job
  [jtype args & body]
  `(defrecord ~jtype []
     org.quartz.StatefulJob
     (execute [this ~@args]
       ~@body)))

(def-stateful-job Job
  [ctx]
  (prn "######## the job is running ###########")
  (Thread/sleep 10000)
  (println "########### the job has done.   ####################"))


(defn start []
  (let [s (-> (qs/initialize) qs/start)
        job  (j/build
              (j/of-type Job)
              (j/with-identity (j/key "job1")))
        trigger (t/build
                 (t/with-identity (t/key "trigger1"))
                 (t/start-now)
                 (t/with-schedule (schedule
                                   (with-repeat-count 10)
                                   (with-interval-in-milliseconds 200))))]
    (qs/schedule s job trigger)))

When I call the start function , the job do not run. And I check mysql database, the QRTZ_LOCKS table has two row.

MyClusteredScheduler    STATE_ACCESS
MyClusteredScheduler    TRIGGER_ACCESS

I am not sure whether the lock block the trigger to fire the job.
And I have no idea how to fix it.

Remove quartzite.date-time

Remove quartzite.date-time as all of that functionality is now in clj-time, often with improvements in correctness or extensibility.

Incorrect build function definition?

I just started to use quartzite and became stuck with job definition. From documentation (which is otherwise really good), I defined job:

(j/build
    (j/of-type NoOpJob)
    (j/with-identity (j/key "jobs.noop.1")))

But this was compiled red.

I checked of-type and with-identity and they are both with arity 2, so the documentation example is probably incorrect and shall read:

(-> (j/build)
    (j/of-type NoOpJob)
    (j/with-identity (j/key "jobs.noop.1")))

This goes green compiled, but not executable. build macro creates inside instance of JobBuilder but has ^JobDetail type hint which causes ClassCastException.

P.S. If this is valid, then same problem might be with build for triggers.

Eastwood error: unused-meta-on-macro

Getting some eastwood errors on a project:

unused-meta-on-macro: Macro invocation of 'clojurewerkz.quartzite.jobs/build' has metadata with keys (:tag) that are almost certainly ignored.

Unable to use DSL effectively

I'm trying to create a trigger that runs once every day at a specified time.
The code for that is as follows:

(t/build
  (t/with-identity "something")
  (t/with-schedule
    (qsdi/schedule
      (qsdi/starting-daily-at (qsdi/time-of-day hours mins 0)))))

But this doesn't do what I intended it to do, running the job once every minute instead.
I've switched to using cron-expressions for now, but would like to know what's the correct way to this.

TBH I find quartzite's documentation to be severely lacking - there are numerous functions with similar names but no docstring telling what they're supposed to be doing.
What's the difference between every-day and on-every-day, for example? They have similar names and the same arglist.

Graceful shutdown

I'm working with application that uses quartzite as scheduling jobs.

The job is triggered by time interval and it takes few minutes to finish itself.

If the program is retrieving shutdown signal it stops scheduler by (shutdown scheduler) but now the running job is just closed without notifying anyone.

Is it possible to monitor the jobs state or wait if job is running to finish it?

In quartz there is @DisallowConcurrentExecution-annotation. Is it possible to use that with quartzite?

Database connection with System/Component and Quartzite jobs

Hey, I'd like to have a job that does a daily update on the database. However, the database connection pool is defined as a component (in System). If I pass the connection as context to job it doesn't work since it gets coerced. What would be the idiomatic way of accessing database connections (or other variables) from within a job?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.