1 /* 2 * Hunt - A refined core library for D programming language. 3 * 4 * Copyright (C) 2018-2019 HuntLabs 5 * 6 * Website: https://www.huntlabs.net/ 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.concurrency.CompletableFuture; 13 14 import hunt.concurrency.Future; 15 import hunt.concurrency.Promise; 16 17 import hunt.Exceptions; 18 import hunt.Functions; 19 20 /** 21 * <p>A CompletableFuture that is also a Promise.</p> 22 * 23 * @param <S> the type of the result 24 */ 25 class Completable(S) : CompletableFuture!S , Promise!S { 26 override 27 void succeeded(S result) { 28 complete(result); 29 } 30 31 override 32 void failed(Exception x) { 33 completeExceptionally(x); 34 } 35 36 string id() { 37 return _id; 38 } 39 40 void id(string id) { _id = id;} 41 42 this() { 43 _id = "undefined"; 44 super(); 45 } 46 47 private string _id; 48 } 49 50 51 52 /** 53 */ 54 class CompletableFuture(T) 55 { 56 57 /** 58 * If not already completed, sets the value returned by {@link 59 * #get()} and related methods to the given value. 60 * 61 * @param value the result value 62 * @return {@code true} if this invocation caused this CompletableFuture 63 * to transition to a completed state, else {@code false} 64 */ 65 bool complete(T value) { 66 completeValue(value); 67 postComplete(); 68 return false; 69 } 70 71 private T result; 72 private bool m_isDone; 73 74 this() { } 75 76 this(T r) { 77 completeValue(r); 78 } 79 80 //this(Supplier!T supplier) 81 //{ 82 // assert(supplier !is null); 83 // this.supplier = supplier; 84 // m_isDone = false; 85 //} 86 87 bool isDone() { 88 return m_isDone; 89 } 90 91 T get() { 92 return result; 93 } 94 95 void cancel() { 96 if(m_cancelled) 97 return; 98 m_cancelled = true; 99 postComplete(); 100 } 101 102 bool isCancelled() { 103 return m_cancelled; 104 } 105 private bool m_cancelled; 106 107 bool completeExceptionally(Throwable ex) { 108 if (ex is null) throw new NullPointerException(""); 109 // bool triggered = internalComplete(new AltResult(ex)); 110 altResult = ex; 111 postComplete(); 112 return false; 113 } 114 115 private Throwable altResult; 116 117 private void completeValue(T r) { 118 result = r; 119 m_isDone = true; 120 } 121 122 /** 123 * Pops and tries to trigger all reachable dependents. Call only 124 * when known to be done. 125 */ 126 private void postComplete() { 127 /* 128 * On each step, variable f holds current dependents to pop 129 * and run. It is extended along only one path at a time, 130 * pushing others to avoid unbounded recursion. 131 */ 132 // debug writeln("postComplete in thread ", Thread.getThis().id); 133 // m_isDone = true; 134 foreach(Consumer!T a; acceptList) 135 a(result); 136 } 137 138 CompletableFuture!T thenAccept(Consumer!T action) { 139 // CompletableFuture!void d = new CompletableFuture!void(); 140 if(m_isDone) { 141 // d.completeValue(result); 142 action(result); 143 } else { 144 acceptList ~= action; 145 } 146 147 return this; 148 } 149 150 private Consumer!T[] acceptList; 151 // private CompletableFuture!void[] acceptList; 152 153 /* ------------- Encoding and decoding outcomes -------------- */ 154 155 // static class AltResult { // See above 156 // Throwable ex; // null only for NIL 157 // this(Throwable x) { this.ex = x; } 158 // } 159 160 }