SlideShare a Scribd company logo
Norman Richards
orb@nostacktrace.comImmutant
Clojure Web Development
$ lein new compojure myapp
$ lein ring server
Congratulations, you now have a Clojure
web application listening on port 3000!
Immutant
What about?
? database
? messaging
? scheduling
? clustering
? production
Immutant
+ Based on JBoss AS 7
+ Makes use of Clojure standards (ring)
+ Production-ready stack out of the box
Setup
+ add immutant plugin to ~/.lein/profiles.clj
{:user
{:plugins [[lein-immutant "1.0.0"]]}
Setup
$ lein immutant install
Downloading http://repository-projectodd.forge.cloudbees.com/release/org/immutant/immutant-dist/1.0.0/immutant-dist-1.0.0-slim.zip
done!
Extracting /var/folders/jw/p379vgcn62q51q4_95xm1v6m0000gp/T/lein-immutant-8041099c-b2c5-4342-ac81-9e3986dfcbd2/immutant-dist-1.0.0-slim.zip
Extracted /Users/norman/.immutant/releases/immutant-1.0.0-slim
Linking /Users/norman/.immutant/current to /Users/norman/.immutant/releases/immutant-1.0.0-slim
The following versions of Immutant are installed to /Users/norman/.immutant
(* is currently active via /Users/norman/.immutant/current):
* 1.0.0 (type: slim)
Setup
$ lein immutant deploy
Deployed myapp to /Users/norman/.immutant/current/jboss/standalone/deployments/myapp.clj
Setup
$ lein immutant run
Starting Immutant: /Users/norman/.immutant/current/jboss/bin/standalone.sh
=========================================================================
JBoss Bootstrap Environment
JBOSS_HOME: /Users/norman/.immutant/current/jboss
JAVA: java
JAVA_OPTS: -server -XX:+UseCompressedOops -Xms64m -Xmx512m -XX:MaxPermSize=256m -Djava.net.preferIPv4Stack=true -
Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true
=========================================================================
16:13:01,823 INFO [org.jboss.modules] (main) JBoss Modules version 1.2.0.CR1
16:13:02,294 INFO [org.jboss.msc] (main) JBoss MSC version 1.0.4.GA
16:13:02,344 INFO [org.jboss.as] (MSC service thread 1-6) JBAS015899: JBoss AS 7.2.x.slim.incremental.6 "Janus" starting
...
...
...
16:13:12,534 INFO [org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss AS 7.2.x.slim.incremental.6 "Janus" started
in 10969ms - Started 128 of 175 services (46 services are passive or on-demand)
Setup
$ lein immutant run --clustered
...
...
16:17:44,573 INFO [org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss AS 7.2.x.slim.incremental.6 "Janus" started
in 10170ms - Started 130 of 223 services (92 services are passive or on-demand)
Housekeeping
$ lein immutant undeploy
Undeployed /Users/norman/.immutant/releases/immutant-1.0.0-slim/jboss/standalone/deployments/myapp.clj
Housekeeping
$ lein immutant env
immutant-home: /Users/norman/.immutant/current
jboss-home: /Users/norman/.immutant/current/jboss
Housekeeping
$ lein immutant list
The following applications are deployed to /Users/norman/.immutant/current:
blue-app.clj (status: deployed)
red-app.clj (status: deployed)
Modules
+ immutant.web
+ immutant.xa
+ immutant.cache
+ immutant.messaging
+ immutant.jobs
+ immutant.daemons
immutant.web
(defproject somewebapp "0.1.0-SNAPSHOT"
;; ...
:plugins [[lein-ring "0.8.5"]]
:ring {:handler somewebapp.handler/app})
(defproject somewebapp "0.1.0-SNAPSHOT"
;; ...
:immutant {:nrepl-port 0
:context-path "/"})
immutant.web
(ns immutant.init
  (:require [somewebapp.handler :as handler]
            [immutant.web :as web]))
(web/start "/" handler/app)
immutant.web
/context-prefix /handler-path /app-path
From the deployment
From immutant init From your application
immutant.web
(def app
(-> app-routes
;; additional handlers
handler/site))
(def app
(let [store (immutant.web.session/servlet-store)]
(-> app-routes
;; additional handlers
(handler/site {:session {:store store}}))))
immutant.web
+ works with non-ring apps (eg. Pedestal)
+ control over virtual hosts and context paths
+ can dynamically start/stop endpoints
+ minimal changes to your code, framework agnostic
immutant.xa
(defonce my-datasource
(xa/datasource "mydb" {:adapter "postgres"
:host "33.33.33.50"
:username "db-user"
:password "db-password"
:database "my-awesome-db"}))
(def db-spec {:datasource my-datasource})
immutant.xa
(jdbc/with-connection db-spec
(jdbc/do-commands
"CREATE TABLE widgets (
name VARCHAR NOT NULL PRIMARY KEY,
count VARCHAR NOT NULL DEFAULT 0);"))
(jdbc/with-connection db-spec
(korma.core/select :widgets))
(def db-spec {:name "java:jboss/datasources/SomeExternalDS"})
immutant.xa
(defn new-widget [name number]
(let [widget {:name name :count number}]
(xa/transaction
(jdbc/with-connection db-spec
(korma/insert :widgets (korma/values widget)))
(msg/publish "/queue/widgets" widget))))
+ integrates well with Clojure database things
+ XA transactions are tricky and hard to test
+ Most apps use many non-XA resources
+ database config can be external and shared
immutant.xa
+ All the immutant services are XA
immutant.cache
(def game-cache
(cache/create "game"
:persist true
:sync true))
 
(def job-cache
(cache/create "job-status"
:ttl 10
:idle 1
:units :minutes))
immutant.cache
(defn add-points [player points]
(let [current-score (get game-cache player 0)
new-score (+ current-score points)]
(cache/put game-cache player new-score)
new-score))
immutant.cache
+ Really easy to use
+ Interface isn’t very Clojure-like, needs abstraction
+ Should a data grid be deployed along side app?
+ Infinispan does much more than caching
immutant.messaging
(msg/start "/queue/orders")
(msg/start "/topic/new-widget")
 
(defn process-order [order]
(println "processing" order)
(msg/publish "/topic/new-widget" {:widget order}))
 
(defonce widgets (atom []))
(defn cache-widget [widget]
(swap! widgets #(conj % widget))
(println "I have" (count @widgets) "widgets"))
 
(msg/listen "/queue/orders" process-order)
(msg/listen "/topic/new-widget" cache-widget)
immutant.messaging
+ Priority, expiration, persistence, properties
+ Easy to toss around Clojure data structures
+ Pipelines are very cool
+ Topics and queues
immutant.jobs
(defonce heartbeat (atom nil))
 
(defn send-heartbeat []
(riemann/send-event {:service "heartbeat" :state "ok" :metric 1}))
 
(defn heartbeat-thread [every-n-sec]
(while true
(send-heartbeat)
(Thread/sleep (* 1000 every-n-sec))))
 
(defn start-heartbeat []
(swap! heartbeat
(fn [heartbeat]
(or heartbeat
(doto (Thread. #(heartbeat-thread 10))
.start)))))
 
(defn stop-heartbeat []
(swap! heartbeat
(fn [heartbeat] (when heartbeat (.stop heartbeat)))))
immutant.jobs
(defn send-heartbeat []
(riemann/send-event {:service "heartbeat" :state "ok" :metric 1}))
 
(defn start-heartbeat []
(jobs/schedule :heartbeat
send-heartbeat
:every 10000))
 
(defn stop-heartbeat []
(jobs/unschedule :heartbeat))
+ Also supports CRON-like scheduling syntax
+ Can be used for ad-hoc jobs
+ Not easy to see what jobs are scheduled/running
+ Jobs can be on all nodes or just one
immutant.jobs
immutant.daemons
(defonce listener (atom nil))
(defn start-listener []
(swap! listener
(fn [listener]
(msg/listen "/queue/guesses" play/handle-guess))))
 
(defn stop-listener []
(swap! listener
(fn [listener]
(when listener
(msg/unlisten listener)))))
 
(daemon/daemonize "guess-listener"
start-listener
stop-listener
:singleton true)
immutant.daemons
+ Can be long running
+ Singleton processes can be reliably setup
+ Manage application-specific services
The PI Game
π
https://github.com/orb/pi-game
PI Game Demo
+ EDN api to get state and send actions
+ Game state saved in persistent cache
+ Clojurescript front end, Clojure back end
+
+
+ Player actions are sent to guess queue
Singleton daemon creates one listener per cluster
Demo uses two immutant nodes with nginx in front
But...
• Works out of the box
• It’s good Clojure - not “Clojure 2
Enterprise Edition”
• Best solution for multiple applications
• Best solution when you want to work
with Java or Ruby apps
• JBoss is production tested
• Responsive dev team
• Are these the services you
would have chosen?
• It’s one big blob, not lots of
composable blocks
• Does it fit your application
architecture?
• Does it fit your ops strategy?
Yes
• App was ring/jetty - using our own custom startup
• Wanted to split our APIs out and modularize app instead of
deploying as a monolithic app
• Wanted to be able to support rolling updates across nodes
• Liked the idea of being able to bring mature clustering, caching
and messaging into the app almost for free
Immutant at Threatgrid
• Transition to Immutant was very fast and required only minor
changes to our customized startup code
• We ran into a few small issues, but the Immutant dev team had
almost immediate fixes/workarounds.
• Transitional codebase still supports running outside Immutant,
so we haven’t been able to leverage some features
• Ops team strongly prefers individual services that can be
managed independently - Immutant is one big ball
• Our web nodes and data nodes scale separately - Immutant
seems to prefer a more homogenous deployment
• Immutant a la carte would really hit a sweet spot
And.... we’re still deciding

More Related Content

What's hot

11 tools for your PHP devops stack
11 tools for your PHP devops stack11 tools for your PHP devops stack
11 tools for your PHP devops stack
Kris Buytaert
 
How Flipkart scales PHP
How Flipkart scales PHPHow Flipkart scales PHP
How Flipkart scales PHP
Siddhartha Reddy Kothakapu
 
Apache Sling - The whys and the hows
Apache Sling - The whys and the howsApache Sling - The whys and the hows
Apache Sling - The whys and the hows
Robert Munteanu
 
Getting Started with Rails on GlassFish (Hands-on Lab) - Spark IT 2010
Getting Started with Rails on GlassFish (Hands-on Lab) - Spark IT 2010Getting Started with Rails on GlassFish (Hands-on Lab) - Spark IT 2010
Getting Started with Rails on GlassFish (Hands-on Lab) - Spark IT 2010
Arun Gupta
 
Performance Improvements in Browsers
Performance Improvements in BrowsersPerformance Improvements in Browsers
Performance Improvements in Browsers
jeresig
 
Scalable Django Architecture
Scalable Django ArchitectureScalable Django Architecture
Scalable Django Architecture
Rami Sayar
 
PuppetCamp SEA 1 - Using Vagrant, Puppet, Testing & Hadoop
PuppetCamp SEA 1 - Using Vagrant, Puppet, Testing & HadoopPuppetCamp SEA 1 - Using Vagrant, Puppet, Testing & Hadoop
PuppetCamp SEA 1 - Using Vagrant, Puppet, Testing & Hadoop
Walter Heck
 
Puppet for dummies - ZendCon 2011 Edition
Puppet for dummies - ZendCon 2011 EditionPuppet for dummies - ZendCon 2011 Edition
Puppet for dummies - ZendCon 2011 Edition
Joshua Thijssen
 
Vagrant crash course
Vagrant crash courseVagrant crash course
Vagrant crash course
Marcus Deglos
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life better
ZendCon
 
Powering the Next Generation Services with Java Platform - Spark IT 2010
Powering the Next Generation Services with Java Platform - Spark IT 2010Powering the Next Generation Services with Java Platform - Spark IT 2010
Powering the Next Generation Services with Java Platform - Spark IT 2010
Arun Gupta
 
DockerCon EU 2018 - Dockerfile Best Practices
DockerCon EU 2018 - Dockerfile Best PracticesDockerCon EU 2018 - Dockerfile Best Practices
DockerCon EU 2018 - Dockerfile Best Practices
Tibor Vass
 
Spring Booted, But... @JCConf 16', Taiwan
Spring Booted, But... @JCConf 16', TaiwanSpring Booted, But... @JCConf 16', Taiwan
Spring Booted, But... @JCConf 16', Taiwan
Pei-Tang Huang
 
What is Rack Hijacking API
What is Rack Hijacking APIWhat is Rack Hijacking API
What is Rack Hijacking API
Nomo Kiyoshi
 
Rebooting a Cloud
Rebooting a CloudRebooting a Cloud
Rebooting a Cloud
Jesse Robbins
 

What's hot (20)

Scaling Django
Scaling DjangoScaling Django
Scaling Django
 
11 tools for your PHP devops stack
11 tools for your PHP devops stack11 tools for your PHP devops stack
11 tools for your PHP devops stack
 
How Flipkart scales PHP
How Flipkart scales PHPHow Flipkart scales PHP
How Flipkart scales PHP
 
Apache Sling - The whys and the hows
Apache Sling - The whys and the howsApache Sling - The whys and the hows
Apache Sling - The whys and the hows
 
Getting Started with Rails on GlassFish (Hands-on Lab) - Spark IT 2010
Getting Started with Rails on GlassFish (Hands-on Lab) - Spark IT 2010Getting Started with Rails on GlassFish (Hands-on Lab) - Spark IT 2010
Getting Started with Rails on GlassFish (Hands-on Lab) - Spark IT 2010
 
Vagrant
VagrantVagrant
Vagrant
 
Performance Improvements in Browsers
Performance Improvements in BrowsersPerformance Improvements in Browsers
Performance Improvements in Browsers
 
Scalable Django Architecture
Scalable Django ArchitectureScalable Django Architecture
Scalable Django Architecture
 
Dev ops for developers
Dev ops for developersDev ops for developers
Dev ops for developers
 
PuppetCamp SEA 1 - Using Vagrant, Puppet, Testing & Hadoop
PuppetCamp SEA 1 - Using Vagrant, Puppet, Testing & HadoopPuppetCamp SEA 1 - Using Vagrant, Puppet, Testing & Hadoop
PuppetCamp SEA 1 - Using Vagrant, Puppet, Testing & Hadoop
 
Puppet for dummies - ZendCon 2011 Edition
Puppet for dummies - ZendCon 2011 EditionPuppet for dummies - ZendCon 2011 Edition
Puppet for dummies - ZendCon 2011 Edition
 
DevOps for Developers
DevOps for DevelopersDevOps for Developers
DevOps for Developers
 
Vagrant crash course
Vagrant crash courseVagrant crash course
Vagrant crash course
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life better
 
Powering the Next Generation Services with Java Platform - Spark IT 2010
Powering the Next Generation Services with Java Platform - Spark IT 2010Powering the Next Generation Services with Java Platform - Spark IT 2010
Powering the Next Generation Services with Java Platform - Spark IT 2010
 
DockerCon EU 2018 - Dockerfile Best Practices
DockerCon EU 2018 - Dockerfile Best PracticesDockerCon EU 2018 - Dockerfile Best Practices
DockerCon EU 2018 - Dockerfile Best Practices
 
BPMS1
BPMS1BPMS1
BPMS1
 
Spring Booted, But... @JCConf 16', Taiwan
Spring Booted, But... @JCConf 16', TaiwanSpring Booted, But... @JCConf 16', Taiwan
Spring Booted, But... @JCConf 16', Taiwan
 
What is Rack Hijacking API
What is Rack Hijacking APIWhat is Rack Hijacking API
What is Rack Hijacking API
 
Rebooting a Cloud
Rebooting a CloudRebooting a Cloud
Rebooting a Cloud
 

Similar to Immutant

Large-scaled Deploy Over 100 Servers in 3 Minutes
Large-scaled Deploy Over 100 Servers in 3 MinutesLarge-scaled Deploy Over 100 Servers in 3 Minutes
Large-scaled Deploy Over 100 Servers in 3 Minutes
Hiroshi SHIBATA
 
Automated Java Deployments With Rpm
Automated Java Deployments With RpmAutomated Java Deployments With Rpm
Automated Java Deployments With Rpm
Martin Jackson
 
Trying and evaluating the new features of GlusterFS 3.5
Trying and evaluating the new features of GlusterFS 3.5Trying and evaluating the new features of GlusterFS 3.5
Trying and evaluating the new features of GlusterFS 3.5
Keisuke Takahashi
 
Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)
Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)
Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)
DECK36
 
Saltstack - Orchestration & Application Deployment
Saltstack - Orchestration & Application DeploymentSaltstack - Orchestration & Application Deployment
Saltstack - Orchestration & Application Deployment
inovex GmbH
 
DevOps(4) : Ansible(2) - (MOSG)
DevOps(4) : Ansible(2) - (MOSG)DevOps(4) : Ansible(2) - (MOSG)
DevOps(4) : Ansible(2) - (MOSG)
Soshi Nemoto
 
Democratizing Serverless
Democratizing ServerlessDemocratizing Serverless
Democratizing Serverless
Shaun Smith
 
Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)
William Farrell
 
An Ensemble Core with Docker - Solving a Real Pain in the PaaS
An Ensemble Core with Docker - Solving a Real Pain in the PaaS An Ensemble Core with Docker - Solving a Real Pain in the PaaS
An Ensemble Core with Docker - Solving a Real Pain in the PaaS
Erik Osterman
 
Advanced iOS Build Mechanics, Sebastien Pouliot
Advanced iOS Build Mechanics, Sebastien PouliotAdvanced iOS Build Mechanics, Sebastien Pouliot
Advanced iOS Build Mechanics, Sebastien PouliotXamarin
 
Warsaw MuleSoft Meetup - Runtime Fabric
Warsaw MuleSoft Meetup - Runtime FabricWarsaw MuleSoft Meetup - Runtime Fabric
Warsaw MuleSoft Meetup - Runtime Fabric
Patryk Bandurski
 
OpenStack API's and WSGI
OpenStack API's and WSGIOpenStack API's and WSGI
OpenStack API's and WSGI
Mike Pittaro
 
Zero to scaleable in ten minutes
Zero to scaleable in ten minutesZero to scaleable in ten minutes
Zero to scaleable in ten minutes
Matt Walters
 
Universal Userland
Universal UserlandUniversal Userland
Universal Userland
Sean Chittenden
 
Toolbox of a Ruby Team
Toolbox of a Ruby TeamToolbox of a Ruby Team
Toolbox of a Ruby Team
Arto Artnik
 
introduction to node.js
introduction to node.jsintroduction to node.js
introduction to node.js
orkaplan
 
Re-Design with Elixir/OTP
Re-Design with Elixir/OTPRe-Design with Elixir/OTP
Re-Design with Elixir/OTP
Mustafa TURAN
 
Node azure
Node azureNode azure
Node azure
Emanuele DelBono
 
Load testing with Blitz
Load testing with BlitzLoad testing with Blitz
Load testing with Blitz
Lindsay Holmwood
 
Intro To Node.js
Intro To Node.jsIntro To Node.js
Intro To Node.js
Chris Cowan
 

Similar to Immutant (20)

Large-scaled Deploy Over 100 Servers in 3 Minutes
Large-scaled Deploy Over 100 Servers in 3 MinutesLarge-scaled Deploy Over 100 Servers in 3 Minutes
Large-scaled Deploy Over 100 Servers in 3 Minutes
 
Automated Java Deployments With Rpm
Automated Java Deployments With RpmAutomated Java Deployments With Rpm
Automated Java Deployments With Rpm
 
Trying and evaluating the new features of GlusterFS 3.5
Trying and evaluating the new features of GlusterFS 3.5Trying and evaluating the new features of GlusterFS 3.5
Trying and evaluating the new features of GlusterFS 3.5
 
Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)
Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)
Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)
 
Saltstack - Orchestration & Application Deployment
Saltstack - Orchestration & Application DeploymentSaltstack - Orchestration & Application Deployment
Saltstack - Orchestration & Application Deployment
 
DevOps(4) : Ansible(2) - (MOSG)
DevOps(4) : Ansible(2) - (MOSG)DevOps(4) : Ansible(2) - (MOSG)
DevOps(4) : Ansible(2) - (MOSG)
 
Democratizing Serverless
Democratizing ServerlessDemocratizing Serverless
Democratizing Serverless
 
Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)
 
An Ensemble Core with Docker - Solving a Real Pain in the PaaS
An Ensemble Core with Docker - Solving a Real Pain in the PaaS An Ensemble Core with Docker - Solving a Real Pain in the PaaS
An Ensemble Core with Docker - Solving a Real Pain in the PaaS
 
Advanced iOS Build Mechanics, Sebastien Pouliot
Advanced iOS Build Mechanics, Sebastien PouliotAdvanced iOS Build Mechanics, Sebastien Pouliot
Advanced iOS Build Mechanics, Sebastien Pouliot
 
Warsaw MuleSoft Meetup - Runtime Fabric
Warsaw MuleSoft Meetup - Runtime FabricWarsaw MuleSoft Meetup - Runtime Fabric
Warsaw MuleSoft Meetup - Runtime Fabric
 
OpenStack API's and WSGI
OpenStack API's and WSGIOpenStack API's and WSGI
OpenStack API's and WSGI
 
Zero to scaleable in ten minutes
Zero to scaleable in ten minutesZero to scaleable in ten minutes
Zero to scaleable in ten minutes
 
Universal Userland
Universal UserlandUniversal Userland
Universal Userland
 
Toolbox of a Ruby Team
Toolbox of a Ruby TeamToolbox of a Ruby Team
Toolbox of a Ruby Team
 
introduction to node.js
introduction to node.jsintroduction to node.js
introduction to node.js
 
Re-Design with Elixir/OTP
Re-Design with Elixir/OTPRe-Design with Elixir/OTP
Re-Design with Elixir/OTP
 
Node azure
Node azureNode azure
Node azure
 
Load testing with Blitz
Load testing with BlitzLoad testing with Blitz
Load testing with Blitz
 
Intro To Node.js
Intro To Node.jsIntro To Node.js
Intro To Node.js
 

More from Norman Richards

An Adventure in Serverless ClojureScript
An Adventure in Serverless ClojureScriptAn Adventure in Serverless ClojureScript
An Adventure in Serverless ClojureScript
Norman Richards
 
Logic programming a ruby perspective
Logic programming a ruby perspectiveLogic programming a ruby perspective
Logic programming a ruby perspective
Norman Richards
 
Lisp 1.5 - Running history
Lisp 1.5 - Running historyLisp 1.5 - Running history
Lisp 1.5 - Running history
Norman Richards
 
The Logical Burrito - pattern matching, term rewriting and unification
The Logical Burrito - pattern matching, term rewriting and unificationThe Logical Burrito - pattern matching, term rewriting and unification
The Logical Burrito - pattern matching, term rewriting and unificationNorman Richards
 
Deconstructing the Functional Web with Clojure
Deconstructing the Functional Web with ClojureDeconstructing the Functional Web with Clojure
Deconstructing the Functional Web with Clojure
Norman Richards
 
core.logic introduction
core.logic introductioncore.logic introduction
core.logic introduction
Norman Richards
 
Vert.X mini-talk
Vert.X mini-talkVert.X mini-talk
Vert.X mini-talk
Norman Richards
 
The Lambda Calculus and The JavaScript
The Lambda Calculus and The JavaScriptThe Lambda Calculus and The JavaScript
The Lambda Calculus and The JavaScript
Norman Richards
 

More from Norman Richards (8)

An Adventure in Serverless ClojureScript
An Adventure in Serverless ClojureScriptAn Adventure in Serverless ClojureScript
An Adventure in Serverless ClojureScript
 
Logic programming a ruby perspective
Logic programming a ruby perspectiveLogic programming a ruby perspective
Logic programming a ruby perspective
 
Lisp 1.5 - Running history
Lisp 1.5 - Running historyLisp 1.5 - Running history
Lisp 1.5 - Running history
 
The Logical Burrito - pattern matching, term rewriting and unification
The Logical Burrito - pattern matching, term rewriting and unificationThe Logical Burrito - pattern matching, term rewriting and unification
The Logical Burrito - pattern matching, term rewriting and unification
 
Deconstructing the Functional Web with Clojure
Deconstructing the Functional Web with ClojureDeconstructing the Functional Web with Clojure
Deconstructing the Functional Web with Clojure
 
core.logic introduction
core.logic introductioncore.logic introduction
core.logic introduction
 
Vert.X mini-talk
Vert.X mini-talkVert.X mini-talk
Vert.X mini-talk
 
The Lambda Calculus and The JavaScript
The Lambda Calculus and The JavaScriptThe Lambda Calculus and The JavaScript
The Lambda Calculus and The JavaScript
 

Recently uploaded

UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
Elena Simperl
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
RTTS
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
Fwdays
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
Product School
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 

Recently uploaded (20)

UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 

Immutant

  • 2. Clojure Web Development $ lein new compojure myapp $ lein ring server Congratulations, you now have a Clojure web application listening on port 3000!
  • 3. Immutant What about? ? database ? messaging ? scheduling ? clustering ? production
  • 4. Immutant + Based on JBoss AS 7 + Makes use of Clojure standards (ring) + Production-ready stack out of the box
  • 5. Setup + add immutant plugin to ~/.lein/profiles.clj {:user {:plugins [[lein-immutant "1.0.0"]]}
  • 6. Setup $ lein immutant install Downloading http://repository-projectodd.forge.cloudbees.com/release/org/immutant/immutant-dist/1.0.0/immutant-dist-1.0.0-slim.zip done! Extracting /var/folders/jw/p379vgcn62q51q4_95xm1v6m0000gp/T/lein-immutant-8041099c-b2c5-4342-ac81-9e3986dfcbd2/immutant-dist-1.0.0-slim.zip Extracted /Users/norman/.immutant/releases/immutant-1.0.0-slim Linking /Users/norman/.immutant/current to /Users/norman/.immutant/releases/immutant-1.0.0-slim The following versions of Immutant are installed to /Users/norman/.immutant (* is currently active via /Users/norman/.immutant/current): * 1.0.0 (type: slim)
  • 7. Setup $ lein immutant deploy Deployed myapp to /Users/norman/.immutant/current/jboss/standalone/deployments/myapp.clj
  • 8. Setup $ lein immutant run Starting Immutant: /Users/norman/.immutant/current/jboss/bin/standalone.sh ========================================================================= JBoss Bootstrap Environment JBOSS_HOME: /Users/norman/.immutant/current/jboss JAVA: java JAVA_OPTS: -server -XX:+UseCompressedOops -Xms64m -Xmx512m -XX:MaxPermSize=256m -Djava.net.preferIPv4Stack=true - Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true ========================================================================= 16:13:01,823 INFO [org.jboss.modules] (main) JBoss Modules version 1.2.0.CR1 16:13:02,294 INFO [org.jboss.msc] (main) JBoss MSC version 1.0.4.GA 16:13:02,344 INFO [org.jboss.as] (MSC service thread 1-6) JBAS015899: JBoss AS 7.2.x.slim.incremental.6 "Janus" starting ... ... ... 16:13:12,534 INFO [org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss AS 7.2.x.slim.incremental.6 "Janus" started in 10969ms - Started 128 of 175 services (46 services are passive or on-demand)
  • 9. Setup $ lein immutant run --clustered ... ... 16:17:44,573 INFO [org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss AS 7.2.x.slim.incremental.6 "Janus" started in 10170ms - Started 130 of 223 services (92 services are passive or on-demand)
  • 10. Housekeeping $ lein immutant undeploy Undeployed /Users/norman/.immutant/releases/immutant-1.0.0-slim/jboss/standalone/deployments/myapp.clj
  • 11. Housekeeping $ lein immutant env immutant-home: /Users/norman/.immutant/current jboss-home: /Users/norman/.immutant/current/jboss
  • 12. Housekeeping $ lein immutant list The following applications are deployed to /Users/norman/.immutant/current: blue-app.clj (status: deployed) red-app.clj (status: deployed)
  • 13. Modules + immutant.web + immutant.xa + immutant.cache + immutant.messaging + immutant.jobs + immutant.daemons
  • 14. immutant.web (defproject somewebapp "0.1.0-SNAPSHOT" ;; ... :plugins [[lein-ring "0.8.5"]] :ring {:handler somewebapp.handler/app}) (defproject somewebapp "0.1.0-SNAPSHOT" ;; ... :immutant {:nrepl-port 0 :context-path "/"})
  • 15. immutant.web (ns immutant.init   (:require [somewebapp.handler :as handler]             [immutant.web :as web])) (web/start "/" handler/app)
  • 16. immutant.web /context-prefix /handler-path /app-path From the deployment From immutant init From your application
  • 17. immutant.web (def app (-> app-routes ;; additional handlers handler/site)) (def app (let [store (immutant.web.session/servlet-store)] (-> app-routes ;; additional handlers (handler/site {:session {:store store}}))))
  • 18. immutant.web + works with non-ring apps (eg. Pedestal) + control over virtual hosts and context paths + can dynamically start/stop endpoints + minimal changes to your code, framework agnostic
  • 19. immutant.xa (defonce my-datasource (xa/datasource "mydb" {:adapter "postgres" :host "33.33.33.50" :username "db-user" :password "db-password" :database "my-awesome-db"})) (def db-spec {:datasource my-datasource})
  • 20. immutant.xa (jdbc/with-connection db-spec (jdbc/do-commands "CREATE TABLE widgets ( name VARCHAR NOT NULL PRIMARY KEY, count VARCHAR NOT NULL DEFAULT 0);")) (jdbc/with-connection db-spec (korma.core/select :widgets)) (def db-spec {:name "java:jboss/datasources/SomeExternalDS"})
  • 21. immutant.xa (defn new-widget [name number] (let [widget {:name name :count number}] (xa/transaction (jdbc/with-connection db-spec (korma/insert :widgets (korma/values widget))) (msg/publish "/queue/widgets" widget))))
  • 22. + integrates well with Clojure database things + XA transactions are tricky and hard to test + Most apps use many non-XA resources + database config can be external and shared immutant.xa + All the immutant services are XA
  • 23. immutant.cache (def game-cache (cache/create "game" :persist true :sync true))   (def job-cache (cache/create "job-status" :ttl 10 :idle 1 :units :minutes))
  • 24. immutant.cache (defn add-points [player points] (let [current-score (get game-cache player 0) new-score (+ current-score points)] (cache/put game-cache player new-score) new-score))
  • 25. immutant.cache + Really easy to use + Interface isn’t very Clojure-like, needs abstraction + Should a data grid be deployed along side app? + Infinispan does much more than caching
  • 26. immutant.messaging (msg/start "/queue/orders") (msg/start "/topic/new-widget")   (defn process-order [order] (println "processing" order) (msg/publish "/topic/new-widget" {:widget order}))   (defonce widgets (atom [])) (defn cache-widget [widget] (swap! widgets #(conj % widget)) (println "I have" (count @widgets) "widgets"))   (msg/listen "/queue/orders" process-order) (msg/listen "/topic/new-widget" cache-widget)
  • 27. immutant.messaging + Priority, expiration, persistence, properties + Easy to toss around Clojure data structures + Pipelines are very cool + Topics and queues
  • 28. immutant.jobs (defonce heartbeat (atom nil))   (defn send-heartbeat [] (riemann/send-event {:service "heartbeat" :state "ok" :metric 1}))   (defn heartbeat-thread [every-n-sec] (while true (send-heartbeat) (Thread/sleep (* 1000 every-n-sec))))   (defn start-heartbeat [] (swap! heartbeat (fn [heartbeat] (or heartbeat (doto (Thread. #(heartbeat-thread 10)) .start)))))   (defn stop-heartbeat [] (swap! heartbeat (fn [heartbeat] (when heartbeat (.stop heartbeat)))))
  • 29. immutant.jobs (defn send-heartbeat [] (riemann/send-event {:service "heartbeat" :state "ok" :metric 1}))   (defn start-heartbeat [] (jobs/schedule :heartbeat send-heartbeat :every 10000))   (defn stop-heartbeat [] (jobs/unschedule :heartbeat))
  • 30. + Also supports CRON-like scheduling syntax + Can be used for ad-hoc jobs + Not easy to see what jobs are scheduled/running + Jobs can be on all nodes or just one immutant.jobs
  • 31. immutant.daemons (defonce listener (atom nil)) (defn start-listener [] (swap! listener (fn [listener] (msg/listen "/queue/guesses" play/handle-guess))))   (defn stop-listener [] (swap! listener (fn [listener] (when listener (msg/unlisten listener)))))   (daemon/daemonize "guess-listener" start-listener stop-listener :singleton true)
  • 32. immutant.daemons + Can be long running + Singleton processes can be reliably setup + Manage application-specific services
  • 34. PI Game Demo + EDN api to get state and send actions + Game state saved in persistent cache + Clojurescript front end, Clojure back end + + + Player actions are sent to guess queue Singleton daemon creates one listener per cluster Demo uses two immutant nodes with nginx in front
  • 35. But... • Works out of the box • It’s good Clojure - not “Clojure 2 Enterprise Edition” • Best solution for multiple applications • Best solution when you want to work with Java or Ruby apps • JBoss is production tested • Responsive dev team • Are these the services you would have chosen? • It’s one big blob, not lots of composable blocks • Does it fit your application architecture? • Does it fit your ops strategy? Yes
  • 36. • App was ring/jetty - using our own custom startup • Wanted to split our APIs out and modularize app instead of deploying as a monolithic app • Wanted to be able to support rolling updates across nodes • Liked the idea of being able to bring mature clustering, caching and messaging into the app almost for free Immutant at Threatgrid
  • 37. • Transition to Immutant was very fast and required only minor changes to our customized startup code • We ran into a few small issues, but the Immutant dev team had almost immediate fixes/workarounds. • Transitional codebase still supports running outside Immutant, so we haven’t been able to leverage some features • Ops team strongly prefers individual services that can be managed independently - Immutant is one big ball • Our web nodes and data nodes scale separately - Immutant seems to prefer a more homogenous deployment • Immutant a la carte would really hit a sweet spot And.... we’re still deciding