SHARE
TWEET

Untitled

a guest Dec 3rd, 2019 85 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package com.alithya.platon;
  2.  
  3. import static java.util.stream.Collectors.toList;
  4.  
  5. import java.util.ArrayList;
  6. import java.util.Arrays;
  7. import java.util.List;
  8. import java.util.Objects;
  9. import java.util.concurrent.CompletableFuture;
  10. import java.util.concurrent.TimeUnit;
  11. import org.junit.jupiter.api.AfterEach;
  12. import org.junit.jupiter.api.BeforeEach;
  13. import org.junit.jupiter.api.Test;
  14.  
  15. public class RandomTest {
  16.  
  17.     public static final List<String> strings = Arrays.asList("1", "2", "3", "4", "5", "6", "7", "8");
  18.     MyTest myTest = new MyTest();
  19.     long millisBefore; // used to benchmark
  20.  
  21.     @BeforeEach
  22.     void setUp() {
  23.         millisBefore = System.currentTimeMillis();
  24.     }
  25.  
  26.     @AfterEach
  27.     void tearDown() {
  28.         System.out.printf("time taken : %.4fs\n",
  29.                 (System.currentTimeMillis() - millisBefore) / 1000d);
  30.     }
  31.  
  32.     @Test
  33.     void oliExample() throws Exception { // 8.04s
  34.         List<CompletableFuture<String>> listOfFutures = strings.stream()
  35.                 .map(myTest::downloadWebPage).collect(toList());
  36.         CompletableFuture<List<String>> futureOfList = CompletableFuture
  37.                 .allOf(listOfFutures.toArray(new CompletableFuture[0]))
  38.                 .thenApply(
  39.                         v -> listOfFutures.stream().map(CompletableFuture::join).collect(toList()));
  40.  
  41.         System.out.println(futureOfList.get()); // blocks here
  42.     }
  43.  
  44.     @Test
  45.     void mySolution() throws Exception { // 8s
  46.         var futures = myTest.getFilteredEventsFaster(strings);
  47.  
  48.         System.out.println(futures.get()); // blocks here
  49.     }
  50.  
  51.     @Test
  52.     void originalProblem() { // 32s
  53.         var orig = strings.stream()
  54.                 .map(myTest::origDownload)
  55.                 .flatMap(List::stream)
  56.                 .collect(toList());
  57.  
  58.         System.out.println(orig.toString());
  59.     }
  60.  
  61.     @Test
  62.     void possiblyTrivial() { // 4s
  63.         var orig = strings.parallelStream()
  64.                 .map(myTest::origDownload)
  65.                 .flatMap(List::stream)
  66.                 .collect(toList());
  67.  
  68.         System.out.println(orig.toString());
  69.     }
  70.  
  71.  
  72. }
  73.  
  74.  
  75. class MyTest {
  76.  
  77.     List<String> origDownload(String webPageLink) {
  78.         try {
  79.             TimeUnit.SECONDS.sleep(4);
  80.         } catch (Exception io) {
  81.             throw new RuntimeException(io);
  82.         } finally {
  83.             return RandomTest.strings;
  84.         }
  85.     }
  86.  
  87.     CompletableFuture<String> downloadWebPage(String webPageLink) {
  88.         return CompletableFuture.supplyAsync(() -> {
  89.             try {
  90.                 TimeUnit.SECONDS.sleep(4);
  91.             } catch (Exception io) {
  92.                 throw new RuntimeException(io);
  93.             } finally {
  94.                 return "downloaded : " + webPageLink;
  95.             }
  96.         });
  97.     }
  98.  
  99.     CompletableFuture<List<String>> getFilteredEventsFaster(List<String> strings) {
  100.  
  101.         /* Collecting the list of all the async requests that build a List<Event>. */
  102.         List<CompletableFuture<List<String>>> completableFutures = strings.stream()
  103.                 .map(api -> getFilteredEventsAsync(strings))
  104.                 .collect(toList());
  105.  
  106.         /* Creating a single Future that contains all the Futures we just created ("flatmap"). */
  107.         CompletableFuture<Void> allFutures = CompletableFuture.allOf(completableFutures
  108.                 .toArray(new CompletableFuture[strings.size()]));
  109.  
  110.         /* When all the Futures have completed, we join them to create merged List<Event>. */
  111.         CompletableFuture<List<String>> allCompletableFutures = allFutures
  112.                 .thenApply(future -> completableFutures.stream()
  113.                         .filter(Objects::nonNull) // we filter out the failed calls
  114.                         .map(CompletableFuture::join)
  115.                         .flatMap(List::stream) // creating a List<Event> from List<List<Event>>
  116.                         .collect(toList())
  117.                 );
  118.  
  119.         return allCompletableFutures;
  120.     }
  121.  
  122.     private static CompletableFuture<List<String>> getFilteredEventsAsync(List<String> strings) {
  123.         /* Manage the Exceptions here to ensure the wrapping Future returns the other calls. */
  124.         return CompletableFuture.supplyAsync(() -> {
  125.             try {
  126.                 TimeUnit.SECONDS.sleep(4);
  127.                 return strings;
  128.             } catch (Exception io) {
  129.                 throw new RuntimeException(io);
  130.             }
  131.         })
  132.                 .exceptionally(ex -> {
  133.                     return null; // gets managed in the wrapping Future
  134.                 });
  135.     }
  136.  
  137. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top