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.FuturePromise; 13 14 import hunt.concurrency.Future; 15 import hunt.concurrency.Promise; 16 17 import hunt.Exceptions; 18 import std.format; 19 import std.datetime; 20 21 import core.thread; 22 import hunt.logging; 23 24 /** 25 */ 26 class FuturePromise(T) : Future!T, Promise!T { 27 private __gshared Exception COMPLETED; 28 private bool _done; 29 private Exception _cause; 30 private T _result; 31 private string _id; 32 33 shared static this() { 34 COMPLETED = new Exception(""); 35 } 36 37 this() { 38 } 39 40 string id() { return _id; } 41 void id(string id) { _id = id; } 42 43 void succeeded(T result) { 44 if (!_done) { 45 _done = true; 46 _result = result; 47 _cause = COMPLETED; 48 } 49 } 50 51 52 void failed(Exception cause) { 53 if (!_done) { 54 _done = true; 55 _cause = cause; 56 } 57 } 58 59 bool cancel(bool mayInterruptIfRunning) { 60 if (!_done) { 61 _done = true; 62 _result = T.init; 63 _cause = new CancellationException(""); 64 return true; 65 } 66 return false; 67 } 68 69 70 bool isCancelled() { 71 if (_done) { 72 try { 73 // _latch.await(); 74 } catch (InterruptedException e) { 75 throw new RuntimeException(e.msg); 76 } 77 return typeid(_cause) == typeid(CancellationException); 78 } 79 return false; 80 } 81 82 bool isDone() { 83 return _done; 84 } 85 86 T get() { 87 // if(!_done) 88 // throw new ExecutionException("Not done yet."); 89 while(!_done) { 90 version(HUNT_DEBUG) warning("Waiting for a promise..."); 91 // FIXME: Needing refactor or cleanup -@zxp at 9/10/2018, 2:11:03 PM 92 // 93 Thread.sleep(20.msecs); 94 } 95 version(HUNT_DEBUG) info("Got a promise"); 96 97 if(_cause is null) { 98 warning("no cause!"); 99 new ExecutionException("no cause!"); 100 } 101 102 if (_cause is COMPLETED) 103 return _result; 104 CancellationException c = cast(CancellationException) _cause; 105 if (c !is null) 106 throw c; 107 throw new ExecutionException(_cause.msg); 108 } 109 110 T get(Duration timeout) { 111 MonoTime before = MonoTime.currTime; 112 while(!_done) { 113 version(HUNT_DEBUG) warning("Waiting for a promise..."); 114 // FIXME: Needing refactor or cleanup -@zxp at 9/10/2018, 2:15:52 PM 115 // 116 Thread.sleep(20.msecs); 117 Duration timeElapsed = MonoTime.currTime - before; 118 if(timeElapsed > timeout) 119 break; 120 } 121 version(HUNT_DEBUG) infof("promise status: isDone=%s", _done); 122 if(!_done) 123 throw new TimeoutException(); 124 125 if (_cause == COMPLETED) 126 return _result; 127 128 TimeoutException t = cast(TimeoutException) _cause; 129 if (t !is null) 130 throw t; 131 132 CancellationException c = cast(CancellationException) _cause; 133 if (c !is null) 134 throw c; 135 136 throw new ExecutionException(_cause.msg); 137 } 138 139 override 140 string toString() { 141 return format("FutureCallback@%x{%b,%b,%s}", toHash(), _done, _cause == COMPLETED, _result); 142 } 143 }