### Install Example Database Source: https://github.com/msolli/proletarian/blob/main/PROJECT_SUMMARY.md Install the example database for development and testing purposes. This command creates a database named 'proletarian'. ```bash # Install example database (creates 'proletarian' database) make examples.db.install ``` -------------------------------- ### Install Example Database Source: https://github.com/msolli/proletarian/blob/main/doc/example-a.md Runs the Makefile target to install the Proletarian example database. This script creates the necessary user, database, schema, tables, and indexes. ```shell $ make examples.db.install DATABASE_NAME=proletarian ./database/install.sh ``` ```text Installing Proletarian Database = = Creating User - - » proletarian role Creating Database - - » proletarian database Creating Schema, Tables, and Index » proletarian schema » proletarian.job table » proletarian.archived_job table » proletarian.job_queue_process_at index Granting Privileges - - » schema privileges » table privileges = = Done Installing Proletarian Database ``` -------------------------------- ### Recreate Example Database Source: https://github.com/msolli/proletarian/blob/main/PROJECT_SUMMARY.md Recreate the example database by first uninstalling and then installing it. This is useful for resetting the database state. ```bash # Recreate database (uninstall then install) make examples.db.recreate ``` -------------------------------- ### Uninstall Example Database Source: https://github.com/msolli/proletarian/blob/main/PROJECT_SUMMARY.md Uninstall the example database. This command removes the database previously installed for development. ```bash # Uninstall example database make examples.db.uninstall ``` -------------------------------- ### Start REPL for Development Source: https://github.com/msolli/proletarian/blob/main/PROJECT_SUMMARY.md Launch a REPL environment with all necessary aliases for development. This can be done using the make command or the Clojure CLI. ```bash # Start REPL with all necessary aliases make repl ``` ```bash # Or with Clojure CLI clj -M:dev:test:examples ``` -------------------------------- ### Install to Local Maven Repository Source: https://github.com/msolli/proletarian/blob/main/PROJECT_SUMMARY.md Install the project's artifact to the local Maven repository. This allows other local projects to depend on this project. ```bash # Install to local Maven repository make mvn.install ``` -------------------------------- ### Worker Output Example Source: https://github.com/msolli/proletarian/blob/main/doc/example-c.md Example output from the Proletarian Queue Worker, showing initial status and ongoing job polling. ```text Number of jobs in :proletarian/default queue: 0 Number of jobs in proletarian.jobs table: 0 Number of jobs in proletarian.archived_jobs table: 0 Starting worker for :proletarian/default queue with polling interval 1 s :proletarian.worker/polling-for-jobs {:worker-thread-id 1, :proletarian.worker/queue-worker-id proletarian[:proletarian/default]} :proletarian.worker/polling-for-jobs {:worker-thread-id 1, :proletarian.worker/queue-worker-id proletarian[:proletarian/default]} [...and so on, until you press Ctrl-C] ``` -------------------------------- ### Create and Start a Queue Worker Source: https://github.com/msolli/proletarian/blob/main/README.md Defines and starts a queue worker. The worker constructor requires a data source and a job handler function. Ensure you have a data-source available and implement the job handler. ```clojure (ns your-app.workers "You'll probably want to use a component state library (Component, Integrant, Mount, or some such) for managing the worker state. For this example we're just def-ing the worker. The queue worker constructor function takes a javax.sql.DataSource as its first argument. You probably already have a data-source at hand in your application already. Here we'll use next.jdbc to get one from a JDBC connection URL. The second argument is the job handler function. Proletarian will invoke this whenever a job is ready for processing. It's a arity-2 function, with the job type (a keyword) as the first argument, and the job's payload as the second argument." (:require [next.jdbc :as jdbc] [proletarian.worker :as worker] [your-app.handlers :as handlers])) (def email-worker (let [ds (jdbc/get-datasource "jdbc:postgresql://...")] (worker/create-queue-worker ds handlers/handle-job!))) (worker/start! email-worker) ``` -------------------------------- ### Queue Worker Output Source: https://github.com/msolli/proletarian/blob/main/doc/example-a.md Example output from the Queue Worker process. It shows the number of jobs in various tables and indicates that the worker has started polling for jobs. ```text Number of jobs in :proletarian/default queue: 0 Number of jobs in proletarian.jobs table: 0 Number of jobs in proletarian.archived_jobs table: 0 Starting worker for :proletarian/default queue with polling interval 5 s :proletarian.worker/polling-for-jobs {:worker-thread-id 1, :proletarian.worker/queue-worker-id proletarian[:proletarian/default]} :proletarian.worker/polling-for-jobs {:worker-thread-id 1, :proletarian.worker/queue-worker-id proletarian[:proletarian/default]} [...and so forth, until you press Ctrl-C] ``` -------------------------------- ### Run PostgreSQL with Docker Source: https://github.com/msolli/proletarian/blob/main/doc/example-a.md Starts a PostgreSQL instance using Docker and exposes it on port 55432. This is useful for running Proletarian with an ephemeral database. ```shell docker run -p 55432:5432 -e POSTGRES_PASSWORD=proletarian postgres ``` -------------------------------- ### Configure Database URL for Docker Source: https://github.com/msolli/proletarian/blob/main/doc/example-a.md Sets the DATABASE_URL environment variable to connect to a PostgreSQL instance running on Docker. Ensure this is set before running database installation or worker commands. ```shell export DATABASE_URL="jdbc:postgresql://localhost:55432/proletarian?user=postgres&password=proletarian" ``` -------------------------------- ### Run Queue Worker Source: https://github.com/msolli/proletarian/blob/main/doc/example-a.md Starts the Proletarian Queue Worker process using the clj command-line tool. This worker polls the default queue for jobs. ```shell clj -X:examples example-a.worker/run ``` -------------------------------- ### Run Proletarian Queue Worker Source: https://github.com/msolli/proletarian/blob/main/doc/example-c.md Starts the Proletarian Queue Worker, which polls the default queue for jobs. It's configured with advanced handler mode, a JVM shutdown hook for graceful shutdown, and an on-shutdown callback. ```shell clj -X:examples example-c.worker/run ``` -------------------------------- ### Run Queue Worker Source: https://github.com/msolli/proletarian/blob/main/doc/example-b.md Starts the Proletarian Queue Worker to poll for jobs. It can be configured with custom retry strategies, failed job handlers, and polling error handlers. The worker can also be configured with specific numbers of worker threads and polling intervals. ```shell clj -X:examples example-b.worker/run ``` ```shell clj -X:examples example-b.worker/run :worker-threads 2 :polling-interval 1 ``` -------------------------------- ### Worker Handling Blocking Job Source: https://github.com/msolli/proletarian/blob/main/doc/example-c.md Shows the worker picking up and starting to handle a blocking job. If interrupted during the sleep, specific shutdown events will be logged. ```text :proletarian.worker/handling-job {:job-type :example-c.enqueue-jobs/blocking-job, ...} Running job :example-c.enqueue-jobs/blocking-job. Payload: {:sleep-ms 10000, :timestamp #inst "..."} Sleeping 10000... If you press Ctrl-C now, you should observe the following events: :proletarian.executor/shutting-down :proletarian.worker/job-interrupted :proletarian.executor/completed-shutdown The current job (timestamp: ...) should then be picked up again when restarting the worker process. If you don't interrupt, then the job will finish and won't be run again. ``` -------------------------------- ### Run All Tests Source: https://github.com/msolli/proletarian/blob/main/PROJECT_SUMMARY.md Execute all project tests using the make command. Alternatively, use the Clojure CLI with specific aliases and the kaocha runner. ```bash # Run all tests make test ``` ```bash # Or directly with Clojure CLI clojure -M:test -m kaocha.runner --config-file test/tests.edn ``` -------------------------------- ### Build JAR Source: https://github.com/msolli/proletarian/blob/main/PROJECT_SUMMARY.md Build a JAR (Java Archive) file for the project. This is a standard step for packaging Java/Clojure applications. ```bash # Build JAR make jar ``` -------------------------------- ### Basic Retry Strategy Configuration Source: https://github.com/msolli/proletarian/blob/main/README.md A simple retry strategy configuration specifying two retries with delays of 1 and 5 seconds respectively. ```clojure {:retries 2 :delays [1000 5000]} ``` -------------------------------- ### Enqueue a Job using clj Source: https://github.com/msolli/proletarian/blob/main/doc/example-a.md Use this command to add a job to the default queue. It will print the job details upon successful enqueuing. ```shell clj -X:examples example-a.enqueue-jobs/run ``` -------------------------------- ### Configure MySQL Job ID Strategy Source: https://github.com/msolli/proletarian/blob/main/CHANGELOG.md Replace the deprecated `:proletarian/uuid-serializer` config option with `:proletarian/job-id-strategy (job-id-strategies/->mysql-uuid-strategy)` for MySQL users to configure the job ID strategy. ```clojure To upgrade, replace with :proletarian/job-id-strategy (job-id-strategies/->mysql-uuid-strategy). ``` -------------------------------- ### Handle Web Requests and Enqueue Jobs Source: https://github.com/msolli/proletarian/blob/main/README.md This handler processes a web request, performs database operations within a transaction, and enqueues a job. It uses next.jdbc for transactions and job enqueuing. ```clojure (ns your-app.handlers "Let's say this is a namespace where you handle web requests. We're going to handle the request, write something to the database, and enqueue a job. We'll do this in a transaction with a little bit of help from next.jdbc." (:require [next.jdbc :as jdbc] [proletarian.job :as job])) (defn some-route-handler [system request] (jdbc/with-transaction [tx (:db system)] ;; Do some business logic here ;; Write some result to the database ;; Enqueue the job: (job/enqueue! tx ::confirmation-email {:email email-address, :other-data-1 :foo, :other-data-2 :bar}) ;; Return a response response)) (defmulti handle-job! "Since we passed this multimethod as the second argument to worker/create-queue-worker, it is called by the Proletarian Queue Worker when a job is ready for execution. Implement this multimethod for your job types." (fn [job-type _payload] job-type)) ;; Implement the handle-job! multimethod for the job type. (defmethod handle-job! ::confirmation-email [job-type {:keys [email-address other-data-1 other-data-2]}] ;; Send the mail and do other time-consuming work here. ) ``` -------------------------------- ### Enqueue CPU-Bound Job Source: https://github.com/msolli/proletarian/blob/main/doc/example-c.md Use this command to enqueue a job that performs a CPU-bound busy-loop for a specified duration. This demonstrates non-interruptible job behavior. ```shell clj -X:examples example-c.enqueue-jobs/run-3 ``` -------------------------------- ### Enqueue core.async Blocking Job Source: https://github.com/msolli/proletarian/blob/main/doc/example-c.md Use this command to enqueue a job that blocks on a core.async timeout channel. This demonstrates interruptible blocking behavior. ```shell clj -X:examples example-c.enqueue-jobs/run-2 ``` -------------------------------- ### Extended Retry Strategy Configuration Source: https://github.com/msolli/proletarian/blob/main/README.md A retry strategy configuration with four retries and delays of 2 seconds for the first retry and 10 seconds for subsequent retries. ```clojure {:retries 4 :delays [2000 10000]} ``` -------------------------------- ### Enqueue a Job and Define a Job Handler Source: https://github.com/msolli/proletarian/blob/main/README.md This snippet shows how to enqueue a job with a specific type and payload, and how to define a job handler function that dispatches based on job type. The handler function receives the job type and payload, and can access system state through closures. ```clojure (require '[proletarian.job :as job]) (defn do-something! [db-conn foo] ;; Do stuff here ;; Enqueue a job: (job/enqueue! db-conn ::job-type-foo foo) ) ;; Pass this function as the second argument to ;; proletarian.worker/create-queue-worker (defn handle-job! [job-type payload] ;; Do the dispatch of job types here. This could maybe invoke a multimethod ;; that dispatches on `job-type`. See Example C. ;; The value of payload is whatever was passed as third argument to ;; job/enqueue! (the value of foo in do-something! in this case) ) ``` -------------------------------- ### core.async Blocking Job Output Source: https://github.com/msolli/proletarian/blob/main/doc/example-c.md Observe this output when a core.async blocking job is picked up by the worker. It shows the job waiting and the expected interruption events if Ctrl-C is pressed. ```text :proletarian.worker/handling-job {:job-type :example-c.enqueue-jobs/async-blocking-job, ...} Running job :example-c.enqueue-jobs/async-blocking-job. Payload: {:timestamp #inst "...", :wait-ms 10000} Waiting on core.async/ exception (ex-data) :retry-after)] {:retries 2 :delays [retry-after]})) ``` -------------------------------- ### Enqueue Blocking Job Source: https://github.com/msolli/proletarian/blob/main/doc/example-c.md Enqueues a new blocking job to the :proletarian/default queue. This job is designed to sleep for 10 seconds. ```shell clj -X:examples example-c.enqueue-jobs/run-1 ``` -------------------------------- ### Custom Logging Function for Queue Worker Source: https://github.com/msolli/proletarian/blob/main/README.md Configures a custom logger for the queue worker using clojure.tools.logging. The logger function maps internal event keywords to logging levels and calls the log function. ```clojure (ns your-app.workers (:require [clojure.tools.logging :as log] [next.jdbc :as jdbc] [proletarian.worker :as worker] [your-app.handlers :as handlers])) (defn log-level [x] (case x ::worker/queue-worker-shutdown-error :error ::worker/handle-job-exception-with-interrupt :error ::worker/handle-job-exception :error ::worker/job-worker-error :error ::worker/polling-for-jobs :debug :info)) (defn logger [x data] (log/logp (log-level x) x data)) (def worker (let [ds (jdbc/get-datasource "jdbc:postgresql://...")] (worker/create-queue-worker ds handlers/handle-job! {:proletarian/log logger}))) ``` -------------------------------- ### Blocking Job Enqueued Output Source: https://github.com/msolli/proletarian/blob/main/doc/example-c.md Output indicating a new blocking job has been added to the queue, including its ID, type, and payload. ```text Adding new blocking job to :proletarian/default queue: {:job-id #uuid "...", :job-type :example-c.enqueue-jobs/blocking-job, :payload {:sleep-ms 10000, :timestamp #inst "..."}} ``` -------------------------------- ### Failed Job Handler Function Signature Source: https://github.com/msolli/proletarian/blob/main/doc/example-b.md Signature for the function called when a job permanently fails after exhausting all retries. Used for logging or alerting. ```clojure (defn handle-failed-job! [{:proletarian.job/keys [payload attempts] :as _job} exception] ...) ``` -------------------------------- ### Update MySQL Job Timestamps to UTC Source: https://github.com/msolli/proletarian/blob/main/CHANGELOG.md Use this SQL query to update existing job timestamps in MySQL to UTC if your system timezone is not UTC. Adjust 'Europe/Oslo' to your specific timezone. ```sql UPDATE proletarian.job SET process_at = CONVERT_TZ(process_at, 'Europe/Oslo', 'UTC'); ``` -------------------------------- ### Update PostgreSQL Job Timestamps to UTC Source: https://github.com/msolli/proletarian/blob/main/CHANGELOG.md Use this SQL query to update existing job timestamps in PostgreSQL to UTC if your system timezone is not UTC. Adjust 'Europe/Oslo' to your specific timezone. ```sql UPDATE proletarian.job SET process_at = (process_at AT TIME ZONE 'Europe/Oslo') AT TIME ZONE 'UTC'; ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.