Skip to content

Commit f451a6a

Browse files
committed
adding a centralized process spawner so processes started by PL can be easily cleaned up
1 parent ec3fcca commit f451a6a

File tree

2 files changed

+148
-0
lines changed

2 files changed

+148
-0
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
<?php
2+
3+
/*!
4+
* Process Spawner
5+
*
6+
* Copyright (c) 2016 Dave Olsen, http://dmolsen.com
7+
* Licensed under the MIT license
8+
*
9+
* Provide a single instance of spawning background processes related to Pattern Lab
10+
* Hopefully makes ctrl+c truly clean-up the mess of background processes
11+
*
12+
*/
13+
14+
namespace PatternLab\Console;
15+
16+
use \PatternLab\Config;
17+
use \PatternLab\Console;
18+
use \PatternLab\Console\Commands\WatchCommand;
19+
use \PatternLab\Console\ProcessSpawnerEvent;
20+
use \PatternLab\Dispatcher;
21+
use \PatternLab\Timer;
22+
use \Symfony\Component\Process\Process;
23+
24+
class ProcessSpawner {
25+
26+
protected $pluginProcesses;
27+
28+
/**
29+
* Set-up a default var
30+
*/
31+
public function __construct() {
32+
33+
// dispatch event and build the appropriate processes
34+
$event = new ProcessSpawnerEvent();
35+
$dispatcherInstance = Dispatcher::getInstance();
36+
$dispatcherInstance->dispatch('processSpawner.getPluginProcesses',$event);
37+
$this->pluginProcesses = $event->getPluginProcesses();
38+
39+
}
40+
41+
/**
42+
* Spawn the passed commands and those collected from plugins
43+
* @param {Array} a list of commands to spawn
44+
* @param {Boolean} if this should be run in quiet mode
45+
*/
46+
public function spawn($commands = array(), $quiet = false) {
47+
48+
// set-up a default
49+
$processes = array();
50+
51+
// add the default processes sent to the spawner
52+
if (!empty($commands)) {
53+
foreach ($commands as $command) {
54+
$processes[] = $this->buildProcess($command);
55+
}
56+
}
57+
58+
// add the processes sent to the spawner from plugins
59+
foreach ($this->pluginProcesses as $pluginProcess) {
60+
$processes[] = $this->buildProcess($pluginProcess);
61+
}
62+
63+
// start the processes
64+
foreach ($processes as $process) {
65+
$process["process"]->start();
66+
}
67+
68+
// now monitor and output as appropriate
69+
while (true) {
70+
foreach ($processes as $process) {
71+
if ($process["process"]->isRunning()) {
72+
if (!$quiet && $process["output"]) {
73+
print $process["process"]->getIncrementalOutput();
74+
}
75+
}
76+
}
77+
usleep(100000);
78+
}
79+
80+
}
81+
82+
protected function buildProcess($commandOptions) {
83+
84+
if (is_string($commandOptions)) {
85+
86+
$process = new Process(escapeshellcmd((string) $commandOptions));
87+
return array("process" => $process, "output" => true);
88+
89+
} else if (is_array($commandOptions)) {
90+
91+
$commandline = escapeshellcmd((string) $commandOptions["command"]);
92+
$cwd = isset($commandOptions["cwd"]) ? $commandOptions["cwd"] : null;
93+
$env = isset($commandOptions["env"]) ? $commandOptions["env"] : null;
94+
$input = isset($commandOptions["input"]) ? $commandOptions["input"] : null;
95+
$timeout = isset($commandOptions["timeout"]) ? $commandOptions["timeout"] : 60;
96+
$options = isset($commandOptions["options"]) ? $commandOptions["options"] : array();
97+
$idle = isset($commandOptions["idle"]) ? $commandOptions["idle"] : null;
98+
$output = isset($commandOptions["output"]) ? $commandOptions["output"] : true;
99+
100+
$process = new Process($commandline, $cwd, $env, $input, $timeout, $options);
101+
102+
// double-check idle
103+
if (!empty($idle)) {
104+
$process->setIdleTimeout($idle);
105+
}
106+
107+
return array("process" => $process, "output" => $output);
108+
109+
}
110+
111+
}
112+
113+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
/*!
4+
* Process Spawner Event Class
5+
*
6+
* Copyright (c) 2016 Dave Olsen, http://dmolsen.com
7+
* Licensed under the MIT license
8+
*
9+
* Handle the process needs of plugins
10+
*
11+
*/
12+
13+
namespace PatternLab\Console;
14+
15+
use \Symfony\Component\EventDispatcher\Event as SymfonyEvent;
16+
17+
class ProcessSpawnerEvent extends SymfonyEvent {
18+
19+
protected $pluginProcesses;
20+
21+
public function __construct() {
22+
$this->pluginProcesses = array();
23+
}
24+
25+
public function addPluginProcesses($processes = array()) {
26+
if (!empty($processes)) {
27+
$this->pluginProcesses = array_merge($this->pluginProcesses, $processes);
28+
}
29+
}
30+
31+
public function getPluginProcesses() {
32+
return $this->pluginProcesses;
33+
}
34+
35+
}

0 commit comments

Comments
 (0)