SlideShare une entreprise Scribd logo
1  sur  37
Télécharger pour lire hors ligne
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

Contenu connexe

Tendances

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 stackKris Buytaert
 
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 howsRobert 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 2010Arun Gupta
 
Performance Improvements in Browsers
Performance Improvements in BrowsersPerformance Improvements in Browsers
Performance Improvements in Browsersjeresig
 
Scalable Django Architecture
Scalable Django ArchitectureScalable Django Architecture
Scalable Django ArchitectureRami 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 & HadoopWalter Heck
 
Puppet for dummies - ZendCon 2011 Edition
Puppet for dummies - ZendCon 2011 EditionPuppet for dummies - ZendCon 2011 Edition
Puppet for dummies - ZendCon 2011 EditionJoshua Thijssen
 
Vagrant crash course
Vagrant crash courseVagrant crash course
Vagrant crash courseMarcus 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 betterZendCon
 
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 2010Arun Gupta
 
DockerCon EU 2018 - Dockerfile Best Practices
DockerCon EU 2018 - Dockerfile Best PracticesDockerCon EU 2018 - Dockerfile Best Practices
DockerCon EU 2018 - Dockerfile Best PracticesTibor Vass
 
Spring Booted, But... @JCConf 16', Taiwan
Spring Booted, But... @JCConf 16', TaiwanSpring Booted, But... @JCConf 16', Taiwan
Spring Booted, But... @JCConf 16', TaiwanPei-Tang Huang
 
What is Rack Hijacking API
What is Rack Hijacking APIWhat is Rack Hijacking API
What is Rack Hijacking APINomo Kiyoshi
 

Tendances (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
 

Similaire à 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 MinutesHiroshi SHIBATA
 
Automated Java Deployments With Rpm
Automated Java Deployments With RpmAutomated Java Deployments With Rpm
Automated Java Deployments With RpmMartin 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.5Keisuke 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 Deploymentinovex 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 ServerlessShaun 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 FabricPatryk Bandurski
 
OpenStack API's and WSGI
OpenStack API's and WSGIOpenStack API's and WSGI
OpenStack API's and WSGIMike Pittaro
 
Zero to scaleable in ten minutes
Zero to scaleable in ten minutesZero to scaleable in ten minutes
Zero to scaleable in ten minutesMatt Walters
 
Toolbox of a Ruby Team
Toolbox of a Ruby TeamToolbox of a Ruby Team
Toolbox of a Ruby TeamArto Artnik
 
introduction to node.js
introduction to node.jsintroduction to node.js
introduction to node.jsorkaplan
 
Re-Design with Elixir/OTP
Re-Design with Elixir/OTPRe-Design with Elixir/OTP
Re-Design with Elixir/OTPMustafa TURAN
 
Intro To Node.js
Intro To Node.jsIntro To Node.js
Intro To Node.jsChris Cowan
 

Similaire à 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
 

Plus de Norman Richards

An Adventure in Serverless ClojureScript
An Adventure in Serverless ClojureScriptAn Adventure in Serverless ClojureScript
An Adventure in Serverless ClojureScriptNorman Richards
 
Logic programming a ruby perspective
Logic programming a ruby perspectiveLogic programming a ruby perspective
Logic programming a ruby perspectiveNorman Richards
 
Lisp 1.5 - Running history
Lisp 1.5 - Running historyLisp 1.5 - Running history
Lisp 1.5 - Running historyNorman 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 ClojureNorman Richards
 
The Lambda Calculus and The JavaScript
The Lambda Calculus and The JavaScriptThe Lambda Calculus and The JavaScript
The Lambda Calculus and The JavaScriptNorman Richards
 

Plus de 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
 

Dernier

EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 

Dernier (20)

EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 

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