Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

JDD2015: Panta rhei or Reactive Java in practice - Tomasz Kowalczewski

146 views

Published on

PANTA RHEI OR REACTIVE JAVA IN PRACTICE

RxJava is a library for building asynchronous and event based services using simple and powerful api. During this workshop we will create an application composed from several smaller services. These services will process requests and responses in an asynchronous manner. We will investigate advantages and drawbacks of this approach and see how RxJava helps us express such API in a way that is clear, maintainable, composable and testable. Starting from very basic RxJava usages we will venture into more demanding use cases and look how such aspects of our application as monitoring, error handling, timeouts, logging, parallelism and back pressure. APIs of internal components will also be modeled as observable sequences. This exercise is not designed to make you adopt reactive approach in every possible corner of your codebase but rather to provide fresh look at how simple and complex tasks alike can be modeled as streams and provide insight into where RxJava is and where is not a good fit.

Published in: Software
  • Be the first to comment

  • Be the first to like this

JDD2015: Panta rhei or Reactive Java in practice - Tomasz Kowalczewski

  1. 1. Panta rhei by Tomasz Kowalczewski Reactive Java in practice
  2. 2. EXAMPLES REPOSITORY https://github.com/tkowalcz/rx-java-pantha-rhei
  3. 3. REACTIVE, ASYNCHRONOUS People has been doing it for years (Re)invented time and again by big companies and/or in high performance products Now every company may need to operate at that scale As users demand more and faster we need tools to do it right
  4. 4. SYNCHRONOUS DESIGN List<String> tweets = client.getNextTweets(); List<Tweet> validTweets = Lists.newArrayList(); for (String jsonTweet : tweets) {
 Tweet tweet = gson.fromJson(jsonTweet, Tweet.class); Image image; image = download(tweet.getUser().getProfileImage()); Tweet.setImage(image); 
 if (tweet.isValidTweet()) { validTweets.add(tweet); } }
  5. 5. DECOMPOSING INDIVIDUAL OPERATIONS List<String> tweets = client.getNextTweets(); List<Tweet> validTweets = Lists.newArrayList(); for (String jsonTweet : tweets) {
 Tweet tweet = gson.fromJson(jsonTweet, Tweet.class); Image image; image = download(tweet.getUser().getProfileImage()); Tweet.setImage(image); 
 if (tweet.isValidTweet()) { validTweets.add(tweet); } }
  6. 6. DECOMPOSING INDIVIDUAL OPERATIONS List<String> tweets = client.getNextTweets(); List<Tweet> validTweets = Lists.newArrayList(); for (String jsonTweet : tweets) {
 Tweet tweet = gson.fromJson(jsonTweet, Tweet.class); Image image; image = download(tweet.getUser().getProfileImage()); Tweet.setImage(image); 
 if (tweet.isValidTweet()) { validTweets.add(tweet); } }
  7. 7. DECOMPOSING INDIVIDUAL OPERATIONS List<String> tweets = client.getNextTweets(); List<Tweet> validTweets = Lists.newArrayList(); for (String jsonTweet : tweets) {
 Tweet tweet = gson.fromJson(jsonTweet, Tweet.class); Image image; image = download(tweet.getUser().getProfileImage()); Tweet.setImage(image); 
 if (tweet.isValidTweet()) { validTweets.add(tweet); } }
  8. 8. DECOMPOSING INDIVIDUAL OPERATIONS List<String> tweets = client.getNextTweets(); List<Tweet> validTweets = Lists.newArrayList(); for (String jsonTweet : tweets) {
 Tweet tweet = gson.fromJson(jsonTweet, Tweet.class); Image image; image = download(tweet.getUser().getProfileImage()); Tweet.setImage(image); 
 if (tweet.isValidTweet()) { validTweets.add(tweet); } }
  9. 9. DECOMPOSING INDIVIDUAL OPERATIONS List<String> tweets = client.getNextTweets(); List<Tweet> validTweets = Lists.newArrayList(); for (String jsonTweet : tweets) {
 Tweet tweet = gson.fromJson(jsonTweet, Tweet.class); Image image; image = download(tweet.getUser().getProfileImage()); Tweet.setImage(image); 
 if (tweet.isValidTweet()) { validTweets.add(tweet); } }
  10. 10. WHAT IS MISSING? List<String> tweets = client.getNextTweets(); List<Tweet> validTweets = Lists.newArrayList(); for (String jsonTweet : tweets) {
 Tweet tweet = gson.fromJson(jsonTweet, Tweet.class); Image image; image = download(tweet.getUser().getProfileImage()); Tweet.setImage(image); 
 if (tweet.isValidTweet()) { validTweets.add(tweet); } } Error handling Timeouts Monitoring Logging Back pressure Parallelism
  11. 11. SYNCHRONOUS DESIGN List<String> tweets = client.getNextTweets(); List<Tweet> validTweets = Lists.newArrayList(); for (String jsonTweet : tweets) { Tweet tweet = gson.fromJson(jsonTweet, Tweet.class); Image image; image = download(tweet.getUser().getProfileImage()); Tweet.setImage(image); if (tweet.isValidTweet()) { validTweets.add(tweet); } }
  12. 12. WHAT IS MISSING? List<String> tweets = client.getNextTweets(); List<Tweet> validTweets = Lists.newArrayList(); for (String jsonTweet : tweets) {
 Tweet tweet = gson.fromJson(jsonTweet, Tweet.class); Image image; image = download(tweet.getUser().getProfileImage()); Tweet.setImage(image); 
 if (tweet.isValidTweet()) { validTweets.add(tweet); } } Error handling Timeouts Monitoring Logging Back pressure Parallelism
  13. 13. STREAMS (ELEMENTS + TIME) [" ", " ", " ", " ", " "] T1 T2 T3 T4 T5
  14. 14. SUBSCRIBE, MAP, FILTER [" ", " ", " ", " ", " "] subscribe
  15. 15. SUBSCRIBE, MAP, FILTER [" ", " ", " ", " ", " "] [ , , , , ] map subscribe
  16. 16. SUBSCRIBE, MAP, FILTER [" ", " ", " ", " ", " "] [ , , , , ] [ , , ] map filter subscribe
  17. 17. Reactive flow t subscribe onNext* onCompleted | onError unsubscribe
  18. 18. just(1, 1, 2, 3, 5, 8, 13).filter(i -> i % 2 != 0) // 1, 1, 3, 5, 13 just(1, 1, 2, 3, 5, 8, 13).map(i -> i * 2) // 2, 2, 4, 6, 10, 16, 26 Exercise 1a: filter, map
  19. 19. Exercise 1b: take, error handling
  20. 20. Subscriptions flow map filter source … subscribe subscribe subscribe subscribe subscribe onNext onNext onNext onNext subscribeOn If subscription should be made on a different thread observeOn If notifications should be made on a different thread (e.g. UI thread)
  21. 21. Exercise 2: Observable::create
  22. 22. just([1], [1], [2, 3], [5], [], [13]) .flatMap(arr -> just(arr)) // 1, 1, 2, 3, 5, 13 Exercise 3: basic flatMap
  23. 23. Exercise 4: flatMap & async
  24. 24. Exercise 5: error handling
  25. 25. Exercise 6: cache
  26. 26. Exercise 7: testing
  27. 27. Exercise 8a: subjects ?
  28. 28. Exercise 8a: subjects
  29. 29. Exercise 8b: combineLatest
  30. 30. Backpressure
  31. 31. AVAILABLE IN A LANGUAGE OR FRAMEWORK NEAR YOU
  32. 32. FURTHER READING Examples from this presentation https://github.com/tkowalcz/rx-java-pantha-rhei Reactive Java project https://github.com/Netflix/RxJava Other reactive projects http://reactivex.io/ http://rxmarbles.com/ http://davesexton.com/blog/post/To-Use-Subject-Or- Not-To-Use-Subject.aspx https://speakerdeck.com/dlew/reactive-extensions- beyond-the-basics

×