SlideShare una empresa de Scribd logo
1 de 37
Descargar para leer sin conexión
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

Más contenido relacionado

La actualidad más candente

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
 

La actualidad más candente (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 a 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
 

Similar a 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
 

Más 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
 

Más 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
 

Último

New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 

Último (20)

New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 

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