Your SlideShare is downloading. ×
0
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Introducing Immutant
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Introducing Immutant

2,824

Published on

At Clojure/West 2012

At Clojure/West 2012

Published in: Technology
0 Comments
7 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,824
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
22
Comments
0
Likes
7
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Jim Crossley jcrossley@redhat.com Creative  Commons  BY-­SA  3.0Monday, March 19, 2012
  • 2. Agenda • Who,  what,  WHY? • A  fake,  real-­life  application • How? • API  deep-­dive • Clustering,  etcMonday, March 19, 2012
  • 3. Who? • Jim  Crossley  -­  @jcrossley3 • Toby  Crawley  -­  @tcrawley • Bob  McWhirter  -­  Director  of  Polyglot • JBoss  by  Red  HatMonday, March 19, 2012
  • 4. What? • An  app  server  for  Clojure • Inspired  by  TorqueBox • Powered  by  JBoss  AS7 • Started  in  September  2011Monday, March 19, 2012
  • 5. App  Server? • Multiple  apps  running  in  same  JVM • Isolation  via  classloaders • Shared  common  servicesMonday, March 19, 2012
  • 6. Inspired  by  TorqueBox • Make  Ring,  not  War • Clojure  interfaces  to  JBoss   middleware • No  XML • Adapt  AS7  to  the  Clojure   development  common  practicesMonday, March 19, 2012
  • 7. AS7  is  teh  awesome! • Tomcat  for  web • HornetQ  for  messaging • Infinispan  for  caching • Quartz  for  scheduling • Distributed  Transactions  (XA) • Clustering • Management/Monitoring  Monday, March 19, 2012
  • 8. Certified,  fwiw Java  EE  6  Full  ProfileMonday, March 19, 2012
  • 9. Why? • Reduce  incidental  complexity • Simplify  deployment  of  non-­trivial   applications • Simplify  clustering  to  achieve  high-­ availability • Encapsulate  JBoss  services • Exploit  the  JVMMonday, March 19, 2012
  • 10. Polyglot • Leverage  the  best  tool  on  a  single   platform,  regardless  of  language • “ruby  in  the  front,  java  in  the  middle,   clojure  in  the  rear” • Red  Hat  is  committed  to  itMonday, March 19, 2012
  • 11. Maybe  a  fit? • If  you’re  already  using  Jetty,   Memcached,  RabbitMQ,  and/or  Cron • If  you  have  a  polyglot  organization,   especially  Ruby  and  Java • If  you  must  integrate  with  legacy   Java  EEMonday, March 19, 2012
  • 12. Let’s  Get  Real CRUD  can  only  take  you  so  farMonday, March 19, 2012
  • 13. Apps  often  require... • More  than  one  web  interface,  e.g.   administration • Background  processing • Periodic  maintenance • Dynamic  data  sources,  e.g.  REST • ServicesMonday, March 19, 2012
  • 14. But... We’d  still  like  to  treat  the   integration  of  those  components   as  a  single,  versioned  application.Monday, March 19, 2012
  • 15. Consider... • A  tweet-­analysis  app • Filters  the  Twitter  streaming  API  for   brand  keywords • Scrapes  URL’s  from  the  tweets • Stores  weighted  results  of  sentiment   analysisMonday, March 19, 2012
  • 16. Possible  Components... • A  web  app  for  displaying  impressions • An  admin  app  for  defining  users • The  Twitter  streaming  client • The  URL  scraper • A  housekeeper  to  purge  old  dataMonday, March 19, 2012
  • 17. The  Web  Apps ;;;;  Mount  the  ring  handlers (web/start  “/”  brandy.web/app) (web/start  “/admin”  brandy.web/admin)Monday, March 19, 2012
  • 18. The  Message  Queue ;;;;  Where  scrapers  pick  up  their  work (msg/start  “/queue/tweets”) ;;;;  The  scrapers (msg/listen  “/queue/tweets”                          brandy.msg/scrape)Monday, March 19, 2012
  • 19. The  Twitter  Service ;;;;  The  work  producer (daemon/start  “streamer”                              brandy.stream/start                              brandy.stream/stop)Monday, March 19, 2012
  • 20. The  Recurring  Job ;;;;  The  housekeeper (job/schedule  “housekeeper”                              “0  0  0  *  *  ?”                            brandy.job/purge)Monday, March 19, 2012
  • 21. immutant.clj ;;  The  ring  handlers (web/start  “/”            brandy.web/app) (web/start  “/admin”  brandy.web/admin) ;;  Where  scrapers  pick  up  their  work (msg/start  “/queue/tweets”) ;;  The  scrapers (msg/listen  “/queue/tweets”  brandy.msg/scrape) ;;  The  work  producer (daemon/start  “streamer”  brandy.stream/start                                                    brandy.stream/stop) ;;  The  housekeeper (job/schedule  “housekeeper”  “0  0  0  *  *  ?”                                                        brandy.job/purge)Monday, March 19, 2012
  • 22. immutant.clj ;;  The  ring  handlers (web/start  “/”            brandy.web/app) (web/start  “/admin”  brandy.web/admin) ;;  Where  scrapers  pick  up  their  work (msg/start  “/queue/tweets”) ;;  The  scrapers (msg/listen  “/queue/tweets”  brandy.msg/scrape) ;;  The  work  producer (daemon/start  “streamer”  brandy.stream/start                                                    brandy.stream/stop) ;;  The  housekeeper (job/schedule  “housekeeper”  “0  0  0  *  *  ?”                                                        brandy.job/purge)Monday, March 19, 2012
  • 23. immutant.clj ;;  The  ring  handlers (web/start  “/”            brandy.web/app) (web/start  “/admin”  brandy.web/admin) ;;  Where  scrapers  pick  up  their  work (msg/start  “/queue/tweets”) ;;  The  scrapers (msg/listen  “/queue/tweets”  brandy.msg/scrape) ;;  The  work  producer (daemon/start  “streamer”  brandy.stream/start                                                    brandy.stream/stop) ;;  The  housekeeper (job/schedule  “housekeeper”  “0  0  0  *  *  ?”                                                        brandy.job/purge)Monday, March 19, 2012
  • 24. Immutant how?Monday, March 19, 2012
  • 25. Leiningen  Plugin $  lein  plugin  install  lein-­immutant  0.6.0Monday, March 19, 2012
  • 26. Install $  lein  immutant  install  [version]Monday, March 19, 2012
  • 27. Install By  default,  the  plugin  installs   Immutant  beneath        ~/.lein/immutant/Monday, March 19, 2012
  • 28. Run $  lein  immutant  runMonday, March 19, 2012
  • 29. Deploy $  lein  new  myapp $  cd  myapp $  lein  immutant  init $  $EDITOR  immutant.clj $  lein  immutant  deployMonday, March 19, 2012
  • 30. Deploy A  “deployment  descriptor”  is  a   glorified  symlink  written  to   jboss/standalone/deployments Its  contents: {:root  "/the/path/to/your/app"}Monday, March 19, 2012
  • 31. Deploy Each  app  gets  a  dedicated   Clojure  runtime  and  classpath   containing  resolved   dependencies,  src,  lib,  and   resources.Monday, March 19, 2012
  • 32. project.clj (defproject  myapp  "1.2.3"    ...    :immutant  {:init  myapp.core/initialize                          :resolve-­dependencies  true                          :context-­path  "/"                          :swank-­port  4111                          :nrepl-­port  4112})Monday, March 19, 2012
  • 33. Overlay $  lein  immutant  overlay  torquebox $  export  TORQUEBOX_HOME=$IMMUTANT_HOMEMonday, March 19, 2012
  • 34. The  API immutant  namespacesMonday, March 19, 2012
  • 35. The  API • Dynamic  by  design • No  static  xml  files  or  annotations • Modules • Web • Messaging • Caching   • Scheduling • DaemonsMonday, March 19, 2012
  • 36. immutant.web ringMonday, March 19, 2012
  • 37. Web • Supports  any  Ring-­based  handler • Ring  middleware  to  expose  the   Servlet  session • Multiple  web  apps  may  share  the   same  lifecycle  via  “subcontexts”Monday, March 19, 2012
  • 38. Web (require  ‘[immutant.web  :as  web]) (defn  my-­handler  [request]    {:status  200      :headers  {"Content-­Type"  "text/html"}      :body  "Hello  from  Immutant!"}) (web/start  "/hi"  my-­handler)Monday, March 19, 2012
  • 39. Context  paths project.clj (defproject  myapp  "1.2.3"  ...) immutant.clj (web/start  "/"  main) ;;;;  http://localhost:8080/myapp/ (web/start  "/admin"  admin) ;;;;  http://localhost:8080/myapp/adminMonday, March 19, 2012
  • 40. Context  paths project.clj (defproject  myapp  "1.2.3”    :immutant  {:context-­path  "/"}) immutant.clj (web/start  "/"  main) ;;;;  http://localhost:8080/ (web/start  "/admin"  admin) ;;;;  http://localhost:8080/adminMonday, March 19, 2012
  • 41. Session  Replication (require  ‘[immutant.web  :as  web]                  ‘[immutant.web.session  :as  iws]) (web/start  "/"    (ring-­session/wrap-­session        handler        {:store  (iws/servlet-­store)}))Monday, March 19, 2012
  • 42. immutant.messaging hornetqMonday, March 19, 2012
  • 43. Messaging publish-­subscribe point-­to-­pointMonday, March 19, 2012
  • 44. Messaging (require  ‘[immutant.messaging  :as  msg]) (msg/start  "/queue/work") (msg/start  "/topic/news")Monday, March 19, 2012
  • 45. Producers ;;;;  Content  may  be  any  serializable ;;;;  data  structure (msg/publish  “/queue/work”  anything)Monday, March 19, 2012
  • 46. Producers ;;;;  May  be  as  complex  as  necessary (msg/publish  "/queue/work"      {:a  "b"  :c  [1  2  3  {:foo  42}]})Monday, March 19, 2012
  • 47. Producers ;;;;  Support  priority  and  time-­to-­live (msg/publish  “/queue/work”                            a-­message                            :priority  :high                          :ttl  1000)Monday, March 19, 2012
  • 48. Producers ;;;;  Three  message  encodings: ;;;;  :clojure  :json  :text (msg/publish  "/queue/work"      {:a  "b"  :c  [1  2  3  {:foo  42}]}    :encoding  :json)Monday, March 19, 2012
  • 49. Messaging With  TorqueBox,  messages   comprised  of  standard  collections   and  types  are  transparently   interoperable  between  Clojure   and  Ruby  in  either  direction.Monday, March 19, 2012
  • 50. Consumers ;;;;  Block  until  message  arrives (let  [task  (msg/receive  "/queue/work")]    (perform  task))Monday, March 19, 2012
  • 51. Consumers ;;;;  Create  a  lazy  sequence  of  messages (take  4  (msg/message-­seq  “/queue/foo”))Monday, March 19, 2012
  • 52. Consumers (defn  upper-­caser  [s]    (msg/publish  "/topic/upper"                              (.toUpperCase  s))) ;;;;  Register  a  listener (msg/listen  "/queue/lower"  upper-­caser)Monday, March 19, 2012
  • 53. Messaging Automatic  retries,  failover  and   load-­balancing  when  clustered.Monday, March 19, 2012
  • 54. immutant.cache infinispanMonday, March 19, 2012
  • 55. Distributed  Cache • Backed  by  Infinispan  data  grid • Implements  core  Clojure  interfaces •core.cache/CacheProtocol • core.memoize  storeMonday, March 19, 2012
  • 56. Infinispan • Eviction:  FIFO,  LRU • Expiration:  time-­to-­live,  idle  time • Persistence:  write-­through/behind • Transactional:  JTA/XA • MVCC-­based  concurrency • Flexible  clusteringMonday, March 19, 2012
  • 57. Cache  Modes • :local  -­  non-­clustered • Clustered • :invalidated  -­  no  data  shared • :replicated  -­  all  data  shared • :distributed  -­  linear  scalabilityMonday, March 19, 2012
  • 58. :invalidatedMonday, March 19, 2012
  • 59. :replicatedMonday, March 19, 2012
  • 60. :distributedMonday, March 19, 2012
  • 61. immutant.cache • All  caches  have  a  name  and  a  mode   (:local,  :invalidated,  :replicated,   :distributed) • Like-­named  Immutant  caches  are   backed  by  the  same  Infinispan  cacheMonday, March 19, 2012
  • 62. immutant.cache (require  ‘[immutant.cache  :as  ic]) (def  a  (ic/cache  “foo”  :replicated)) (def  b  (ic/cache  “bar”)) (def  c  (ic/cache  “foo”))Monday, March 19, 2012
  • 63. immutant.cache (def  c  (ic/cache  “foo”)) (assoc  c  :a  1) (merge  c  {:b  2  :c  3}) (dissoc  c  :c) c  =>  {:a  1,  :b  2}Monday, March 19, 2012
  • 64. Memoization (require  ‘[immutant.cache  :as  ic]) (def  memoized-­fn  (ic/memo  slow-­fn  “foo”)) (memoized-­fn  1  2  3) (def  c  (ic/cache  “foo”)) c  =>  {[1  2  3]  42}Monday, March 19, 2012
  • 65. Explicit  writes (require  ‘[immutant.cache  :as  ic]) (def  opts  {:ttl  2  :idle  1  :units  :days}) (def  c  (ic/cache  “foo”)) (ic/put  c  key  value  opts) (ic/put-­if-­absent  c  key  value  opts) (ic/put-­if-­present  c  key  value  opts) (ic/put-­if-­replace  c  key  old  new  opts) (ic/delete  c  key)Monday, March 19, 2012
  • 66. immutant.jobs quartzMonday, March 19, 2012
  • 67. Scheduling (require  ‘[immutant.jobs  :as  job]) ;;;;  Once  a  month (job/schedule  "newsletter"                            "0  0  0  1  *  ?"                            news/monthly                            :singleton  true)Monday, March 19, 2012
  • 68. Scheduling “Fire  every  half  hour  from  10am  until  1pm  on   the  third  Friday  of  each  month” 0 */30 10-13 ? * FRI#3 Seconds Minutes Hours DOM Month DOW Year 1-7 1-12 1970- 1-31 SUN- 0-59 0-59 0-23 JAN- 2099 ?LW SAT DEC empty ?L#Monday, March 19, 2012
  • 69. Scheduling (require  ‘[immutant.jobs  :as  job]) (job/at  “name”  “3m”      #(println  “I  fire  after  3  minutes”)) (job/every  “name”  “1d”    #(println  “I  fire  once  a  day”))Monday, March 19, 2012
  • 70. immutant.daemons long-­running  servicesMonday, March 19, 2012
  • 71. Daemons (require  ‘[immutant.daemons  :as  daemon]) (daemon/start  "name"  start-­fn  stop-­fn)Monday, March 19, 2012
  • 72. Daemons (def  response  (atom  nil)) (defn  start  []    (reset!  response        (twitter-­statuses-­filter              (terms)            url-­scraper))) (defn  stop  []      ((:cancel  (meta  @response)))) (daemon/start  "tweets"  start  stop                              :singleton  true)Monday, March 19, 2012
  • 73. Clustering simple  horizontal  scalingMonday, March 19, 2012
  • 74. Clustering $  lein  immutant  run  -­-­clusteredMonday, March 19, 2012
  • 75. Clustering • Session  replication • Robust,  load-­balanced  message   distribution • HA  Singleton • HA  Jobs • InfinispanMonday, March 19, 2012
  • 76. mod_cluster • An  Apache  module  aware  of  JBoss • Reverse  proxy  via  AJP  or  HTTP[S] • Uses  load  statistics  and  deployment   availability  for  intelligent  routing • Optional  session  affinity • FailoverMonday, March 19, 2012
  • 77. mod_clusterMonday, March 19, 2012
  • 78. Coming  soon • Distributed  Transactions  (XA) • OpenShift  integration • Websockets • Better  remote  support • Domain  Mode  (cluster  management)Monday, March 19, 2012
  • 79. http://immutant.org #immutant   @immutantsMonday, March 19, 2012

×