• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

IlyasDeckers / ody-core / 13532154862

25 Feb 2025 10:24PM UTC coverage: 30.374% (+1.7%) from 28.706%
13532154862

push

github

web-flow
Update php.yml

544 of 1791 relevant lines covered (30.37%)

9.13 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/Console/Commands/Server/StartCommand.php
1
<?php
2

3
namespace Ody\Core\Console\Commands\Server;
4

5
use Ody\Core\Console\Style;
6
use Ody\Core\Server\Dependencies;
7
use Ody\Core\Server\Http;
8
use Ody\Swoole\HotReload\Watcher;
9
use Ody\Swoole\ServerState;
10
use Swoole\Process;
11
use Symfony\Component\Console\Attribute\AsCommand;
12
use Symfony\Component\Console\Command\Command;
13
use Symfony\Component\Console\Helper\Table;
14
use Symfony\Component\Console\Input\InputInterface;
15
use Symfony\Component\Console\Input\InputOption;
16
use Symfony\Component\Console\Output\OutputInterface;
17
use Symfony\Component\Console\Question\ChoiceQuestion;
18

19
#[AsCommand(
20
    name: 'server:start',
×
21
    description: 'start http server'
×
22
)]
×
23
class StartCommand extends Command
24
{
25
    private ServerState $serverState;
26
    private Style $io;
27

28
    protected function configure(): void
×
29
    {
30
        $this->addOption(
×
31
            'daemonize',
×
32
            'd',
×
33
            InputOption::VALUE_NONE,
×
34
            'The program works in the background'
×
35
        )->addOption(
×
36
            'watch',
×
37
            'w',
×
38
            InputOption::VALUE_NONE,
×
39
            'If there is a change in the program code, it applies the changes instantly'
×
40
        )->addOption(
×
41
            'phpserver',
×
42
            'p',
×
43
            InputOption::VALUE_NONE,
×
44
            'Run on a build in php server'
×
45
        );
×
46
    }
47

48
    /**
49
     * @throws \Exception
50
     */
51
    protected function execute(InputInterface $input, OutputInterface $output): int
×
52
    {
53
        /*
54
         * load Ody style
55
         */
56
        $this->io = new Style($input, $output);
×
57

58
        /*
59
         * Get a server state instance
60
         */
61
        $this->serverState = ServerState::getInstance();
×
62

63
        if (!$this->canPhpServerRun($input) ||
×
64
            !$this->canDaemonRun($input) ||
×
65
            !$this->checkSslCertificate() ||
×
66
            !Dependencies::check($this->io)
×
67
        ) {
68
            return Command::FAILURE;
×
69
        }
70

71
        if (httpServerIsRunning()) {
×
72
            $this->handleRunningServer($input, $output);
×
73
        }
74

75
        /*
76
         * delete old routes closure cache files
77
         * TODO: implement routes cache
78
         */
79
//        if (file_exists(storagePath('routes'))) {
80
//            $dir = storagePath('routes');
81
//            foreach (array_diff(scandir($dir), ['.', '..']) as $file) {
82
//                unlink("$dir/$file");
83
//            }
84
//        } else {
85
//            mkdir(storagePath('routes'));
86
//        }
87

88
        /*
89
         * create listen message
90
         */
91
        $protocol = !is_null(config('server.ssl.ssl_cert_file')) && !is_null(config('server.ssl.ssl_cert_file')) ? 'https' : 'http';
×
92
        $listenMessage = "listen on $protocol://" . config('server.host') . ':' . config('server.port');
×
93

94
        /*
95
         * send running server
96
         * send listen message
97
         */
98
        $this->io->success('http server running…');
×
99
        $this->io->info($listenMessage, true);
×
100

101
        /*
102
         * check if exist daemonize not send general information
103
         */
104
        if (!$input->getOption('daemonize') && !$input->getOption('phpserver')) {
×
105
            /*
106
             * create socket type of server
107
             */
108
            $serverSocketType = match (config('server.sockType')) {
×
109
                SWOOLE_SOCK_TCP => 'TCP',
×
110
                SWOOLE_SOCK_UDP => 'UDP',
×
111
                default => 'other type'
×
112
            };
×
113

114
            /*
115
             * create general information table
116
             */
117
            $table = new Table($output);
×
118
            $table
×
119
                ->setHeaderTitle('general information')
×
120
                ->setHeaders([
×
121
                    '<fg=#FFCB8B;options=bold> PHP VERSION </>',
×
122
                    '<fg=#FFCB8B;options=bold> ODY VERSION </>',
×
123
                    '<fg=#FFCB8B;options=bold> WORKER COUNT </>',
×
124
                    '<fg=#FFCB8B;options=bold> SOCKET TYPE </>',
×
125
                    '<fg=#FFCB8B;options=bold> WATCH MODE </>'
×
126
                ])
×
127
                ->setRows([
×
128
                    [
×
129
                        '<options=bold> ' . PHP_VERSION . '</>',
×
130
                        '<options=bold> ' . ODY_VERSION . ' </>',
×
131
                        '<options=bold> ' . config('server.additional.worker_num') . '</>',
×
132
                        "<options=bold> $serverSocketType</>",
×
133
                        $input->getOption('watch') ? '<fg=#C3E88D;options=bold> ACTIVE </>' : "<fg=#FF5572;options=bold> DEACTIVE </>"
×
134
                    ],
×
135
                ]);
×
136
            $table->setHorizontal();
×
137
            $table->render();
×
138

139
            /*
140
             * send info message for stop server
141
             */
142
            $this->io->info('Press Ctrl+C to stop the server');
×
143

144
            /*
145
             * create watcher server
146
             */
147
            if ($input->getOption('watch')) {
×
148
                (new Process(function (Process $process) {
×
149
                    $this->serverState->setWatcherProcessId($process->pid);
×
150
                    (new Watcher())->start();
×
151
                }))->start();
×
152
            }
153
        }
154

155
        /*
156
         * create and start server
157
         */
158
        (new Http($input->getOption('phpserver')))
×
159
            ->init($input->getOption('daemonize'));
×
160

161
        return Command::SUCCESS;
×
162
    }
163

164
    private function handleRunningServer(InputInterface $input, OutputInterface $output): void
×
165
    {
166
        $this->io->error('failed to listen server port[' . config('server.host') . ':' . config('server.port') . '], Error: Address already', true);
×
167

168
        $helper = $this->getHelper('question');
×
169
        $question = new ChoiceQuestion(
×
170
            'Do you want the server to terminate? (defaults to no)',
×
171
            ['no', 'yes'],
×
172
            0
×
173
        );
×
174
        $question->setErrorMessage('Your selection is invalid.');
×
175

176
        $answer = $helper->ask($input, $output, $question);
×
177

178

179
        if ($answer != 'yes') {
×
180
            return;
×
181
        }
182

183
        posix_kill($this->serverState->getMasterProcessId(), SIGTERM);
×
184
        posix_kill($this->serverState->getManagerProcessId(), SIGTERM);
×
185

186
        $watcherProcessId = $this->serverState->getWatcherProcessId();
×
187
        if (!is_null($watcherProcessId) && posix_kill($watcherProcessId, SIG_DFL)) {
×
188
            posix_kill($watcherProcessId, SIGTERM);
×
189
        }
190

191
        foreach ($this->serverState->getWorkerProcessIds() as $processId) {
×
192
            posix_kill($processId, SIGTERM);
×
193
        }
194

195
        sleep(1);
×
196
    }
197

198
    private function canDaemonRun(InputInterface $input): bool
×
199
    {
200
        if ($input->getOption('daemonize') && $input->getOption('watch')) {
×
201
            $this->io->error('Cannot use watcher in daemonize mode', true);
×
202
            
203
            return false;
×
204
        }
205
        
206
        return true;
×
207
    }
208

209
    private function canPhpServerRun(InputInterface $input): bool
×
210
    {
211
        if ($input->getOption('daemonize') && $input->getOption('phpserver')) {
×
212
            $this->io->error('Cannot use th PHP server in daemonize mode', true);
×
213

214
            return false;
×
215
        }
216

217
        return true;
×
218
    }
219

220
    private function checkSslCertificate(): bool
×
221
    {
222
        if (!is_null(config('server.ssl.ssl_cert_file')) && !file_exists(config('server.ssl.ssl_cert_file'))) {
×
223
            $this->io->error("ssl certificate file is not found", true);
×
224
            return false;
×
225
        }
226

227
        if (!is_null(config('server.ssl.ssl_cert_file')) && !file_exists(config('server.ssl.ssl_cert_file'))) {
×
228
            $this->io->error("ssl key file is not found", true);
×
229
            return false;
×
230
        }
231

232
        return true;
×
233
    }
234
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc