Work on #403, incorporate review changes
This commit is contained in:
		| @@ -3,10 +3,11 @@ layout: pattern | ||||
| title: Promise | ||||
| folder: promise | ||||
| permalink: /patterns/promise/ | ||||
| categories: Structural | ||||
| categories: Concurrency | ||||
| tags: | ||||
|  - Java | ||||
|  - Concurrency | ||||
|  - Functional | ||||
|  - Reactive | ||||
|  - Difficulty-Intermediate | ||||
| --- | ||||
|  | ||||
|   | ||||
| @@ -74,38 +74,38 @@ | ||||
|       <operations public="true" package="true" protected="true" private="false" static="true"/>     | ||||
|     </display>   | ||||
|   </class>   | ||||
|   <realization id="9">     | ||||
|     <end type="SOURCE" refId="3"/>     | ||||
|     <end type="TARGET" refId="2"/>   | ||||
|   </realization>   | ||||
|   <dependency id="10">     | ||||
|     <end type="SOURCE" refId="8"/>     | ||||
|     <end type="TARGET" refId="1"/>   | ||||
|   </dependency>   | ||||
|   <generalization id="11">     | ||||
|   <generalization id="9">     | ||||
|     <end type="SOURCE" refId="1"/>     | ||||
|     <end type="TARGET" refId="3"/>   | ||||
|   </generalization>   | ||||
|   <dependency id="12">     | ||||
|     <end type="SOURCE" refId="1"/>     | ||||
|     <end type="TARGET" refId="4"/>   | ||||
|   </dependency>   | ||||
|   <dependency id="13">     | ||||
|     <end type="SOURCE" refId="1"/>     | ||||
|     <end type="TARGET" refId="7"/>   | ||||
|   </dependency>   | ||||
|   <dependency id="14">     | ||||
|     <end type="SOURCE" refId="8"/>     | ||||
|     <end type="TARGET" refId="4"/>   | ||||
|   </dependency>   | ||||
|   <dependency id="15">     | ||||
|   <realization id="10">     | ||||
|     <end type="SOURCE" refId="3"/>     | ||||
|     <end type="TARGET" refId="2"/>   | ||||
|   </realization>   | ||||
|   <dependency id="11">     | ||||
|     <end type="SOURCE" refId="1"/>     | ||||
|     <end type="TARGET" refId="6"/>   | ||||
|   </dependency>   | ||||
|   <dependency id="16">     | ||||
|   <dependency id="12">     | ||||
|     <end type="SOURCE" refId="8"/>     | ||||
|     <end type="TARGET" refId="1"/>   | ||||
|   </dependency>   | ||||
|   <dependency id="13">     | ||||
|     <end type="SOURCE" refId="8"/>     | ||||
|     <end type="TARGET" refId="4"/>   | ||||
|   </dependency>   | ||||
|   <dependency id="14">     | ||||
|     <end type="SOURCE" refId="1"/>     | ||||
|     <end type="TARGET" refId="7"/>   | ||||
|   </dependency>   | ||||
|   <dependency id="15">     | ||||
|     <end type="SOURCE" refId="1"/>     | ||||
|     <end type="TARGET" refId="5"/>   | ||||
|   </dependency>   | ||||
|   <dependency id="16">     | ||||
|     <end type="SOURCE" refId="1"/>     | ||||
|     <end type="TARGET" refId="4"/>   | ||||
|   </dependency>   | ||||
|   <classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  | ||||
|     sort-features="false" accessors="true" visibility="true">     | ||||
|     <attributes public="true" package="true" protected="true" private="true" static="true"/>     | ||||
|   | ||||
| @@ -22,6 +22,15 @@ | ||||
|  */ | ||||
| package com.iluwatar.promise; | ||||
|  | ||||
| import java.io.BufferedReader; | ||||
| import java.io.File; | ||||
| import java.io.FileReader; | ||||
| import java.io.FileWriter; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStreamReader; | ||||
| import java.io.Reader; | ||||
| import java.net.URL; | ||||
| import java.util.Map; | ||||
| import java.util.concurrent.CompletableFuture; | ||||
| import java.util.concurrent.ExecutionException; | ||||
| import java.util.concurrent.Executor; | ||||
| @@ -44,6 +53,8 @@ import java.util.concurrent.Executors; | ||||
|  * <li> Prevents callback hell and provides callback aggregation | ||||
|  * </ul> | ||||
|  *  | ||||
|  * <p> | ||||
|  *  | ||||
|  * @see CompletableFuture | ||||
|  */ | ||||
| public class App { | ||||
| @@ -68,23 +79,57 @@ public class App { | ||||
|  | ||||
|   private static void promiseUsage(Executor executor) | ||||
|       throws InterruptedException, ExecutionException { | ||||
|     Promise<Integer> consumedPromise = new Promise<>(); | ||||
|     consumedPromise.fulfillInAsync(() -> { | ||||
|       Thread.sleep(1000); | ||||
|       return 10; | ||||
|     }, executor).then(value -> { | ||||
|       System.out.println("Consumed int value: " + value); | ||||
|     String urlString = "https://raw.githubusercontent.com/iluwatar/java-design-patterns/Promise/promise/README.md"; | ||||
|     Promise<Integer> lineCountPromise = new Promise<String>().fulfillInAsync(() -> { | ||||
|       return downloadFile(urlString); | ||||
|     }, executor).then(fileLocation -> { | ||||
|       return countLines(fileLocation); | ||||
|     }); | ||||
|      | ||||
|     Promise<String> transformedPromise = new Promise<>(); | ||||
|     transformedPromise.fulfillInAsync(() -> { | ||||
|       Thread.sleep(1000); | ||||
|       return "10"; | ||||
|     }, executor).then(value -> { return Integer.parseInt(value); }).then(value -> { | ||||
|       System.out.println("Consumed transformed int value: " + value); | ||||
|     Promise<Map<Character, Integer>> charFrequencyPromise = new Promise<String>().fulfillInAsync(() -> { | ||||
|       return String.valueOf(downloadFile(urlString)); | ||||
|     }, executor).then(fileLocation -> { | ||||
|       return characterFrequency(fileLocation); | ||||
|     }); | ||||
|      | ||||
|     consumedPromise.get(); | ||||
|     transformedPromise.get(); | ||||
|     lineCountPromise.get(); | ||||
|     System.out.println("Line count is: " + lineCountPromise.get()); | ||||
|     charFrequencyPromise.get(); | ||||
|     System.out.println("Char frequency is: " + charFrequencyPromise.get()); | ||||
|   } | ||||
|  | ||||
|   private static Map<Character, Integer> characterFrequency(String fileLocation) { | ||||
|     // TODO Auto-generated method stub | ||||
|     return null; | ||||
|   } | ||||
|  | ||||
|   private static Integer countLines(String fileLocation) { | ||||
|     int lineCount = 0; | ||||
|     try (Reader reader = new FileReader(fileLocation);  | ||||
|         BufferedReader bufferedReader = new BufferedReader(reader);) { | ||||
|       for (String line; (line = bufferedReader.readLine()) != null; ) { | ||||
|         lineCount++; | ||||
|       } | ||||
|     } catch (IOException ex) { | ||||
|       ex.printStackTrace(); | ||||
|     } | ||||
|     return lineCount; | ||||
|   } | ||||
|  | ||||
|   private static String downloadFile(String urlString) throws InterruptedException, IOException { | ||||
|     URL url = new URL(urlString); | ||||
|     File file = File.createTempFile("promise_pattern", null); | ||||
|     try (Reader reader = new InputStreamReader(url.openStream());  | ||||
|         BufferedReader bufferedReader = new BufferedReader(reader); | ||||
|         FileWriter writer = new FileWriter(file)) { | ||||
|       for (String line; (line = bufferedReader.readLine()) != null; ) { | ||||
|         writer.write(line); | ||||
|         writer.write("\n"); | ||||
|       } | ||||
|     } catch (IOException ex) { | ||||
|       ex.printStackTrace(); | ||||
|     } | ||||
|     System.out.println("File downloaded at: " + file.getAbsolutePath()); | ||||
|     return file.getAbsolutePath(); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -120,11 +120,11 @@ public class Promise<T> extends PromiseSupport<T> { | ||||
|    */ | ||||
|   private class ConsumeAction implements Runnable { | ||||
|  | ||||
|     private Promise<T> src; | ||||
|     private Promise<Void> dest; | ||||
|     private Consumer<? super T> action; | ||||
|     private final Promise<T> src; | ||||
|     private final Promise<Void> dest; | ||||
|     private final Consumer<? super T> action; | ||||
|  | ||||
|     ConsumeAction(Promise<T> src, Promise<Void> dest, Consumer<? super T> action) { | ||||
|     private ConsumeAction(Promise<T> src, Promise<Void> dest, Consumer<? super T> action) { | ||||
|       this.src = src; | ||||
|       this.dest = dest; | ||||
|       this.action = action; | ||||
| @@ -147,11 +147,11 @@ public class Promise<T> extends PromiseSupport<T> { | ||||
|    */ | ||||
|   private class TransformAction<V> implements Runnable { | ||||
|  | ||||
|     private Promise<T> src; | ||||
|     private Promise<V> dest; | ||||
|     private Function<? super T, V> func; | ||||
|     private final Promise<T> src; | ||||
|     private final Promise<V> dest; | ||||
|     private final Function<? super T, V> func; | ||||
|  | ||||
|     TransformAction(Promise<T> src, Promise<V> dest, Function<? super T, V> func) { | ||||
|     private TransformAction(Promise<T> src, Promise<V> dest, Function<? super T, V> func) { | ||||
|       this.src = src; | ||||
|       this.dest = dest; | ||||
|       this.func = func; | ||||
|   | ||||
| @@ -33,15 +33,15 @@ import java.util.concurrent.TimeoutException; | ||||
|  */ | ||||
| class PromiseSupport<T> implements Future<T> { | ||||
|  | ||||
|   static final int RUNNING = 1; | ||||
|   static final int FAILED = 2; | ||||
|   static final int COMPLETED = 3; | ||||
|   private static final int RUNNING = 1; | ||||
|   private static final int FAILED = 2; | ||||
|   private static final int COMPLETED = 3; | ||||
|  | ||||
|   final Object lock; | ||||
|   private final Object lock; | ||||
|  | ||||
|   volatile int state = RUNNING; | ||||
|   T value; | ||||
|   Exception exception; | ||||
|   private volatile int state = RUNNING; | ||||
|   private T value; | ||||
|   private Exception exception; | ||||
|  | ||||
|   PromiseSupport() { | ||||
|     this.lock = new Object(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user