22declare(strict_types=1);
26use pmmp\thread\Runnable;
27use pmmp\thread\ThreadSafe;
28use pmmp\thread\ThreadSafeArray;
30use
function array_key_exists;
31use
function igbinary_serialize;
32use
function igbinary_unserialize;
34use
function is_scalar;
35use
function spl_object_id;
68 private static array $threadLocalStorage = [];
71 private ?ThreadSafeArray $progressUpdates =
null;
73 private ThreadSafe|
string|
int|
bool|
null|
float $result =
null;
75 private bool $submitted =
false;
76 private bool $finished =
false;
78 public function run() :
void{
83 $this->finished =
true;
84 AsyncWorker::getNotifier()->wakeupSleeper();
91 return $this->isTerminated();
99 return $this->finished || $this->isTerminated();
102 public function hasResult() : bool{
103 return $this->result !== null;
111 return $this->result->deserialize();
113 return $this->result;
116 public function setResult(mixed $result) : void{
117 $this->result = is_scalar($result) || is_null($result) || $result instanceof ThreadSafe ? $result : new
NonThreadSafeValue($result);
130 public function hasCancelledRun() : bool{
134 public function setSubmitted() : void{
135 $this->submitted = true;
138 public function isSubmitted() : bool{
139 return $this->submitted;
145 abstract public function onRun() : void;
161 public function publishProgress(mixed $progress) : void{
162 $progressUpdates = $this->progressUpdates;
163 if($progressUpdates ===
null){
164 $progressUpdates = $this->progressUpdates =
new ThreadSafeArray();
166 $progressUpdates[] = igbinary_serialize($progress) ??
throw new \InvalidArgumentException(
"Progress must be serializable");
172 public function checkProgressUpdates() : void{
173 $progressUpdates = $this->progressUpdates;
174 if($progressUpdates !==
null){
175 while(($progress = $progressUpdates->shift()) !==
null){
176 $this->onProgressUpdate(igbinary_unserialize($progress));
196 public function onError() : void{
214 protected function storeLocal(string $key, mixed $complexData) : void{
215 self::$threadLocalStorage[spl_object_id($this)][$key] = $complexData;
229 $id = spl_object_id($this);
230 if(!isset(self::$threadLocalStorage[$id]) || !array_key_exists($key, self::$threadLocalStorage[$id])){
231 throw new \InvalidArgumentException(
"No matching thread-local data found on this thread");
234 return self::$threadLocalStorage[$id][$key];
237 final public function __destruct(){
238 $this->reallyDestruct();
239 unset(self::$threadLocalStorage[spl_object_id($this)]);
onProgressUpdate($progress)