1 module hunt.util.thread.Task; 2 3 import hunt.logging; 4 5 import core.atomic; 6 import core.time; 7 import std.format; 8 9 10 enum TaskStatus : ubyte { 11 Ready, 12 Processing, 13 Terminated, 14 Done 15 } 16 17 18 /** 19 * 20 */ 21 abstract class Task { 22 protected shared TaskStatus _status; 23 24 private string _name; 25 26 private MonoTime _createTime; 27 private MonoTime _startTime; 28 private MonoTime _endTime; 29 30 this(string name) { 31 _name = name; 32 _status = TaskStatus.Ready; 33 _createTime = MonoTime.currTime; 34 } 35 36 string name() { 37 return _name; 38 } 39 40 Duration survivalTime() { 41 return _endTime - _createTime; 42 } 43 44 Duration executionTime() { 45 return _endTime - _startTime; 46 } 47 48 Duration lifeTime() { 49 if(_endTime > _createTime) { 50 return survivalTime(); 51 } else { 52 return MonoTime.currTime - _createTime; 53 } 54 } 55 56 TaskStatus status() { 57 return _status; 58 } 59 60 bool isReady() { 61 return _status == TaskStatus.Ready; 62 } 63 64 bool isProcessing() { 65 return _status == TaskStatus.Processing; 66 } 67 68 bool isTerminated() { 69 return _status == TaskStatus.Terminated; 70 } 71 72 bool isDone() { 73 return _status == TaskStatus.Done; 74 } 75 76 void stop() { 77 78 version(HUNT_POOL_DEBUG_MORE) { 79 tracef("The task status: %s", _status); 80 } 81 82 if(!cas(&_status, TaskStatus.Processing, TaskStatus.Terminated) && 83 !cas(&_status, TaskStatus.Ready, TaskStatus.Terminated)) { 84 version(HUNT_POOL_DEBUG) { 85 warningf("The task [%s] stopped. The status is %s", _name, _status); 86 } 87 } 88 } 89 90 void finish() { 91 version(HUNT_POOL_DEBUG_MORE) { 92 tracef("The status of task [%s]: %s", _name, _status); 93 } 94 95 if(cas(&_status, TaskStatus.Processing, TaskStatus.Done) || 96 cas(&_status, TaskStatus.Ready, TaskStatus.Done)) { 97 98 _endTime = MonoTime.currTime; 99 version(HUNT_POOL_DEBUG) { 100 infof("The task [%s] done.", _name); 101 } 102 } else { 103 version(HUNT_POOL_DEBUG) { 104 warningf("Failed to set the status of task [%s] to Done: %s", _name, _status); 105 } 106 } 107 } 108 109 protected void doExecute(); 110 111 void execute() { 112 if(cas(&_status, TaskStatus.Ready, TaskStatus.Processing)) { 113 version(HUNT_POOL_DEBUG_MORE) { 114 tracef("Task %s executing... status: %s", _name, _status); 115 } 116 _startTime = MonoTime.currTime; 117 scope(exit) { 118 finish(); 119 version(HUNT_POOL_DEBUG_MORE) { 120 infof("The task [%s] is done!", _name); 121 } 122 } 123 124 try { 125 doExecute(); 126 } catch(Throwable t) { 127 warningf("task [%s] failed: %s", _name, t.msg); 128 version(HUNT_POOL_DEBUG_MORE) { 129 warning(t); 130 } 131 } 132 } else { 133 warningf("Failed to execute task [%s]. Its status is: %s", _name, _status); 134 } 135 } 136 137 override string toString() { 138 return format("name: %s, status: %s", _name, _status); 139 } 140 141 } 142