Your SlideShare is downloading. ×

Introducing Immutant

2,772

Published on

At Clojure/West 2012

At Clojure/West 2012

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

No Downloads
Views
Total Views
2,772
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
20
Comments
0
Likes
6
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

×