-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathThreader.php
More file actions
114 lines (102 loc) · 3.19 KB
/
Threader.php
File metadata and controls
114 lines (102 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<?php
/**
* @package simple-multi-threader
* @author Mahesh S Warrier <maheshs60@gmail.com>
* @copyright Copyright © Mahesh S Warrier, 2020
* @version 1.0.0
*/
namespace cs\simplemultithreader;
use Opis\Closure\SerializableClosure;
use function Opis\Closure\{serialize as s, unserialize as u};
/**
* Class Threader
* @package codespede\simple-multi-threader
*/
class Threader{
/**
* @var Arguments for the closure
*/
public $arguments;
/**
* @var Directory where jobs will be saved
*/
public $jobsDir = "smt-jobs";
/**
* @var Directory where logs will be saved
*/
public $logsDir = "smt-logs";
/**
* @var Whether to ignore the HUP (hangup) signal in unix based systems
*/
public $nohup = true;
/**
* @var Fully qualified class name of the Helper to be used
*/
public $helperClass = "cs\\simplemultithreader\\CommandHelper";
/**
* Threader constructor.
* @param array $config
*/
public function __construct($config = []){
if (!empty($config)) {
self::configure($this, $config);
}
$this->init();
}
/**
* Threader initializer.
*/
public function init(){
$basePath = $this->getAppBasePath();
if(!file_exists($basePath."/".$this->jobsDir))
mkdir($basePath."/".$this->jobsDir, 0777);
if(!file_exists($basePath."/".$this->logsDir))
mkdir($basePath."/".$this->logsDir, 0777);
}
/**
* Execute the given closure in a separate process.
* @param Closure $closure
* @return string
*/
public function thread($closure){
$jobId = md5(uniqid(rand(), true));
$jobsDir = $this->getAppBasePath()."/".$this->jobsDir;
file_put_contents("{$jobsDir}/{$jobId}_closure.ser", serialize(new SerializableClosure($closure)));
file_put_contents("{$jobsDir}/{$jobId}_arguments.ser", s($this->arguments));
$command = "php '".str_replace('\\', '/', __DIR__)."/thread.php' '{$jobId}' '{$this->jobsDir}' '{$this->logsDir}' '{$this->helperClass}'";
if(!self::isWindows()){
$command = ($this->nohup? "nohup " : "") . "{$command} > /dev/null 2>&1 &";
shell_exec($command);
}
elseif(self::isWindows()){
$WshShell = new \COM("WScript.Shell");
$WshShell->Run($command, 0, false);
}
return $jobId;
}
/**
* Check whether the current environement is Windows or not.
*/
public static function isWindows(){
return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
}
/**
* Configure the threader object with given properties.
* @param Threader $object
* @param array $properties
* @return Threader
*/
public static function configure($object, $properties){
foreach ($properties as $name => $value) {
$object->$name = $value;
}
return $object;
}
/**
* Get the base path of the application
* @return string
*/
public function getAppBasePath(){
return dirname(__DIR__, 4);
}
}