1 | <?php |
||
16 | abstract class AbstractDaemonCommand extends \Symfony\Component\Console\Command\Command |
||
17 | { |
||
18 | use LoggerAwareTrait; |
||
19 | |||
20 | private $commandRunner = null; |
||
21 | |||
22 | 25 | public function __construct(Runner $commandRunner) |
|
28 | |||
29 | /** |
||
30 | * The long running work. |
||
31 | * |
||
32 | * @param InputInterface $input |
||
33 | * @param OutputInterface $output |
||
34 | */ |
||
35 | abstract protected function doWork(InputInterface $input, OutputInterface $output); |
||
36 | |||
37 | 25 | protected function configure() |
|
42 | |||
43 | 24 | protected function execute(InputInterface $input, OutputInterface $output) |
|
44 | { |
||
45 | // Getting arguments |
||
46 | 24 | $action = $input->getArgument('action'); |
|
47 | 24 | $environment = $input->getOption('env'); |
|
48 | 24 | $background = (boolean)$input->getOption('background'); |
|
49 | |||
50 | 24 | $pidFile = $this->getName() . '_' . $environment . '.pid'; |
|
51 | 24 | $fs = new Local(TARTANA_PATH_ROOT . '/var/tmp/'); |
|
52 | 24 | if ($action == 'start') { |
|
53 | 23 | if ($fs->has($pidFile)) { |
|
54 | 3 | $pids = array_filter(explode(':', $fs->read($pidFile)['contents'])); |
|
55 | 3 | if (!empty($pids)) { |
|
56 | 2 | $runningPids = []; |
|
57 | 2 | foreach ($pids as $key => $pid) { |
|
58 | 2 | if (!Util::isPidRunning($pid)) { |
|
59 | 1 | continue; |
|
60 | } |
||
61 | |||
62 | 2 | $runningPids[$key] = $pid; |
|
63 | } |
||
64 | |||
65 | 2 | if ($runningPids == $pids) { |
|
66 | 1 | $this->log( |
|
67 | 1 | 'Daemon for command ' . $this->getName() . ' is already running with the pids ' . implode(':', $pids), |
|
68 | 1 | Logger::INFO |
|
69 | ); |
||
70 | 1 | return; |
|
71 | } else { |
||
72 | // Killing all running processes and starting again |
||
73 | 1 | foreach ($runningPids as $pid) { |
|
74 | 1 | $this->killPid($pid); |
|
75 | } |
||
76 | 1 | $fs->delete($pidFile); |
|
77 | } |
||
78 | } |
||
79 | } |
||
80 | |||
81 | 22 | if ($background) { |
|
82 | // Stripping out the not needed tokens |
||
83 | 1 | $inputString = (string)$input; |
|
84 | 1 | $inputString = str_replace([ |
|
85 | 1 | '-b ', |
|
86 | 1 | '--backgound ', |
|
87 | 1 | $this->getName() . ' ' |
|
88 | 1 | ], '', $inputString); |
|
89 | |||
90 | 1 | $command = Command::getAppCommand($this->getName()); |
|
91 | 1 | $command->setAsync(true); |
|
92 | 1 | $command->setCaptureErrorInOutput(true); |
|
93 | 1 | $command->addArgument($inputString, false); |
|
94 | 1 | $this->getCommandRunner()->execute($command); |
|
95 | |||
96 | 1 | $this->log('Started daemon for command ' . $this->getName() . ' in background mode.', Logger::INFO); |
|
97 | 1 | return; |
|
98 | } |
||
99 | |||
100 | 21 | $this->attachPid($input, getmypid()); |
|
101 | |||
102 | 21 | $this->doWork($input, $output); |
|
103 | 21 | $fs->delete($pidFile); |
|
104 | } |
||
105 | 22 | if ($action == 'stop' && $fs->has($pidFile)) { |
|
106 | 1 | $pids = explode(':', $fs->read($pidFile)['contents']); |
|
107 | 1 | if (!empty($pids)) { |
|
108 | 1 | $this->log( |
|
109 | 1 | 'Daemon for command ' . $this->getName() . ' is running with the pids ' . implode(':', $pids) . ' killing it', |
|
110 | 1 | Logger::INFO |
|
111 | ); |
||
112 | |||
113 | 1 | foreach ($pids as $pid) { |
|
114 | 1 | if (!Util::isPidRunning($pid)) { |
|
115 | 1 | continue; |
|
116 | } |
||
117 | 1 | $this->killPid($pid); |
|
118 | } |
||
119 | } |
||
120 | 1 | $fs->delete($pidFile); |
|
121 | |||
122 | 1 | $this->log('Daemon for command ' . $this->getName() . ' stopped', Logger::INFO); |
|
123 | } |
||
124 | 22 | } |
|
125 | |||
126 | /** |
||
127 | * |
||
128 | * @return \Tartana\Component\Command\Runner |
||
129 | */ |
||
130 | 20 | protected function getCommandRunner() |
|
134 | |||
135 | 21 | protected function attachPid(InputInterface $input, $pid) |
|
152 | |||
153 | 2 | private function killPid($pid) |
|
162 | } |
||
163 |