Skip to content

Instantly share code, notes, and snippets.

@arkadijs
Last active December 17, 2015 00:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arkadijs/5518347 to your computer and use it in GitHub Desktop.
Save arkadijs/5518347 to your computer and use it in GitHub Desktop.
Homework for LDN event Workshop: Clojure http://ldn.lv/events/113852292/

Immutant primer

Homework for LDN event Workshop: Clojure.

Task

Follow Immutant Tutorials and install Leiningen and Immutant.

  1. Create web handler for /?counter=some-name
  2. Create queue to enqueue some-name
  3. Create cache
  4. Read from queue and increment cache(some-name)
  5. Create job to print stats table every 5 sec.
$ curl localhost:8080/?counter=Gopher
Recorded 'Gopher' into the stats table
$ curl localhost:8080/?counter=Gopher
Recorded 'Gopher' into the stats table
$ curl localhost:8080/?counter=Gopher
Recorded 'Gopher' into the stats table
$ curl localhost:8080/?counter=Web
Recorded 'Web' into the stats table
$ curl localhost:8080/?counter=Web
Recorded 'Web' into the stats table
$ curl localhost:8080/?counter=Web
Recorded 'Web' into the stats table
$ curl localhost:8080/?counter=Web
Recorded 'Web' into the stats table
$ curl localhost:8080/?counter=Web
Recorded 'Web' into the stats table
$ 
21:21:43,250 INFO  [stdout] (Thread-81 (HornetQ-client-global-threads-14918829)) Gopher 0 -> 1
21:21:43,704 INFO  [stdout] (Thread-79 (HornetQ-client-global-threads-14918829)) Gopher 1 -> 2
21:21:44,404 INFO  [stdout] (Thread-79 (HornetQ-client-global-threads-14918829)) Gopher 2 -> 3
21:21:45,563 INFO  [stdout] (JobScheduler$cloji.clj_Worker-2) === Stats ===
21:21:45,563 INFO  [stdout] (JobScheduler$cloji.clj_Worker-2) Gopher - 3
21:21:46,532 INFO  [stdout] (Thread-79 (HornetQ-client-global-threads-14918829)) Web 0 -> 1
21:21:46,918 INFO  [stdout] (Thread-81 (HornetQ-client-global-threads-14918829)) Web 1 -> 2
21:21:47,811 INFO  [stdout] (Thread-81 (HornetQ-client-global-threads-14918829)) Web 2 -> 3
21:21:48,183 INFO  [stdout] (Thread-81 (HornetQ-client-global-threads-14918829)) Web 3 -> 4
21:21:48,627 INFO  [stdout] (Thread-80 (HornetQ-client-global-threads-14918829)) Web 4 -> 5
21:21:50,562 INFO  [stdout] (JobScheduler$cloji.clj_Worker-3) === Stats ===
21:21:50,563 INFO  [stdout] (JobScheduler$cloji.clj_Worker-3) Gopher - 3
21:21:50,563 INFO  [stdout] (JobScheduler$cloji.clj_Worker-3) Web - 5

Full solution is 33 non-blank code lines, see below.

Thats includes enterprise grade clustering, messaging, caching, scheduling, race-free counters update.

21:21:16,651 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-1) JBAS015876: Starting deployment of "cloji.clj" (runtime-name: "cloji.clj")
21:21:19,053 INFO  [org.jboss.web] (ServerService Thread Pool -- 68) JBAS018210: Register web context: 
21:21:23,082 INFO  [immutant.cache.core] (pool-8-thread-8) Configuring cache cache0
21:21:23,090 INFO  [org.jboss.as.clustering.infinispan] (pool-8-thread-8) JBAS010282: Stopped cache0 cache from polyglot container
21:21:23,094 INFO  [org.infinispan.jmx.CacheJmxRegistration] (pool-8-thread-8) ISPN000031: MBeans were successfully registered to the platform MBean server.
21:21:23,094 INFO  [org.jboss.as.clustering.infinispan] (pool-8-thread-8) JBAS010281: Started cache0 cache from polyglot container
21:21:25,251 INFO  [immutant.web] (pool-8-thread-8) Registering ring handler at sub-context path: /
21:21:25,462 INFO  [org.hornetq.core.server] (pool-15-thread-1) HQ221005: trying to deploy queue jms.queue.queue0
21:21:25,466 INFO  [org.jboss.as.messaging] (pool-15-thread-1) JBAS011601: Bound messaging object to jndi name java:/queue0
21:21:25,523 INFO  [immutant.jobs] (pool-8-thread-8) Scheduling job job0 with {:every 5000}
21:21:25,527 INFO  [org.quartz.impl.StdSchedulerFactory] (MSC service thread 1-3) Using default implementation for ThreadExecutor
21:21:25,529 INFO  [immutant.runtime] (pool-8-thread-8) Initialized cloji from immutant.init
21:21:25,560 INFO  [org.quartz.core.SchedulerSignalerImpl] (MSC service thread 1-3) Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
21:21:25,561 INFO  [org.quartz.core.QuartzScheduler] (MSC service thread 1-3) Quartz Scheduler v.2.1.5 created.
21:21:25,561 INFO  [org.quartz.simpl.RAMJobStore] (MSC service thread 1-3) RAMJobStore initialized.
21:21:25,561 INFO  [org.quartz.core.QuartzScheduler] (MSC service thread 1-3) Scheduler meta-data: Quartz Scheduler (v2.1.5) 'JobScheduler$cloji.clj' with instanceId 'NON_CLUSTERED'
  Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
  NOT STARTED.
  Currently in standby mode.
  Number of jobs executed: 0
  Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 3 threads.
  Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.

21:21:25,561 INFO  [org.quartz.impl.StdSchedulerFactory] (MSC service thread 1-3) Quartz scheduler 'JobScheduler$cloji.clj' initialized from an externally provided properties instance.
21:21:25,561 INFO  [org.quartz.impl.StdSchedulerFactory] (MSC service thread 1-3) Quartz scheduler version: 2.1.5
21:21:25,561 INFO  [org.quartz.core.QuartzScheduler] (MSC service thread 1-3) JobFactory set to: org.immutant.jobs.JobScheduler@6b55ca
21:21:25,562 INFO  [org.quartz.core.QuartzScheduler] (MSC service thread 1-3) Scheduler JobScheduler$cloji.clj_$_NON_CLUSTERED started.
21:21:25,581 INFO  [org.jboss.as.server] (DeploymentScanner-threads - 2) JBAS018559: Deployed "cloji.clj" (runtime-name : "cloji.clj")
21:21:43,250 INFO  [stdout] (Thread-81 (HornetQ-client-global-threads-14918829)) Gopher 0 -> 1
21:21:43,704 INFO  [stdout] (Thread-79 (HornetQ-client-global-threads-14918829)) Gopher 1 -> 2
21:21:44,404 INFO  [stdout] (Thread-79 (HornetQ-client-global-threads-14918829)) Gopher 2 -> 3
21:21:45,563 INFO  [stdout] (JobScheduler$cloji.clj_Worker-2) === Stats ===
21:21:45,563 INFO  [stdout] (JobScheduler$cloji.clj_Worker-2) Gopher - 3
21:21:46,532 INFO  [stdout] (Thread-79 (HornetQ-client-global-threads-14918829)) Web 0 -> 1
21:21:46,918 INFO  [stdout] (Thread-81 (HornetQ-client-global-threads-14918829)) Web 1 -> 2
21:21:47,811 INFO  [stdout] (Thread-81 (HornetQ-client-global-threads-14918829)) Web 2 -> 3
21:21:48,183 INFO  [stdout] (Thread-81 (HornetQ-client-global-threads-14918829)) Web 3 -> 4
21:21:48,627 INFO  [stdout] (Thread-80 (HornetQ-client-global-threads-14918829)) Web 4 -> 5
21:21:50,562 INFO  [stdout] (JobScheduler$cloji.clj_Worker-3) === Stats ===
21:21:50,563 INFO  [stdout] (JobScheduler$cloji.clj_Worker-3) Gopher - 3
21:21:50,563 INFO  [stdout] (JobScheduler$cloji.clj_Worker-3) Web - 5
(ns cloji.core
(:use [ring.middleware.params])
(:require [immutant.messaging :as messaging]
[immutant.cache :as cache]))
(def cache0 (cache/cache "cache0" :ttl 10, :idle 1, :units :minutes))
(def counters (atom #{}))
(defn handler [{params :params}]
(let [counter (get params "counter" "(unknown)")]
(messaging/publish "queue0" counter)
{:status 200
:headers {"Content-Type" "text/plain"}
:body (str "Recorded '" counter "' into the stats table\n") }))
(defn queue-listener [counter]
(let [current (get cache0 counter 0)
n (+ 1 current)]
(println counter current "->" n)
(cache/put cache0 counter n))
(reset! counters (conj @counters counter)))
(defn job []
(when-not (empty? @counters)
(println "=== Stats ===")
(doseq [counter @counters]
(println counter "-" (get cache0 counter)))))
(ns immutant.init
(:use [cloji.core]
[ring.middleware.params])
(:require [immutant.web :as web]
[immutant.messaging :as messaging]
[immutant.jobs :as jobs]))
(web/start (wrap-params #'handler))
(messaging/start "queue0")
(messaging/listen "queue0" #'queue-listener)
(jobs/schedule "job0" #'job :every 5000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment