Skip to content

Commit 76a2af0

Browse files
committed
wip
1 parent 327dc36 commit 76a2af0

File tree

15 files changed

+603
-430
lines changed

15 files changed

+603
-430
lines changed

app/Config/WorkerMode.php

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class WorkerMode
2727
* - `codeigniter`: Main application instance
2828
* - `superglobals`: Superglobals wrapper
2929
* - `routes`: Router configuration
30+
* - `cache`: Cache instance
3031
*
3132
* @var list<string>
3233
*/
@@ -43,14 +44,6 @@ class WorkerMode
4344
'cache',
4445
];
4546

46-
/**
47-
* Reset Factories
48-
*
49-
* Whether to reset Factories (Models, etc.) between requests.
50-
* Set to false if you want to cache model instances across requests.
51-
*/
52-
public bool $resetFactories = true;
53-
5447
/**
5548
* Garbage Collection
5649
*

system/Commands/Worker/Views/frankenphp-worker.php.tpl

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ $workerConfig = config('WorkerMode');
6868
*---------------------------------------------------------------
6969
*/
7070

71-
$handler = function () use ($app, $workerConfig) {
71+
$handler = static function () use ($app, $workerConfig) {
7272
// Validate database connections before handling request
7373
DatabaseConfig::validateForWorkerMode();
7474
@@ -111,10 +111,8 @@ while (frankenphp_handle_request($handler)) {
111111
// Cleanup connections with uncommitted transactions
112112
DatabaseConfig::cleanupForWorkerMode();
113113

114-
// Reset model/entity instances (if enabled)
115-
if ($workerConfig->resetFactories) {
116-
Factories::reset();
117-
}
114+
// Reset factories
115+
Factories::reset();
118116

119117
// Reset services except persistent ones
120118
Services::resetForWorkerMode($workerConfig);

system/Commands/Worker/WorkerInstall.php

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -127,21 +127,16 @@ protected function showNextSteps(): void
127127
CLI::write('Next Steps:', 'yellow');
128128
CLI::newLine();
129129

130-
CLI::write('1. Review configuration files:', 'white');
131-
CLI::write(' Caddyfile - Adjust port, worker count, max_requests', 'green');
132-
CLI::write(' public/frankenphp-worker.php - Customize state management', 'green');
133-
CLI::newLine();
134-
135-
CLI::write('2. Start FrankenPHP:', 'white');
130+
CLI::write('1. Start FrankenPHP:', 'white');
136131
CLI::write(' frankenphp run', 'green');
137132
CLI::newLine();
138133

139-
CLI::write('3. Test your application:', 'white');
134+
CLI::write('2. Test your application:', 'white');
140135
CLI::write(' curl http://localhost:8080/', 'green');
141136
CLI::newLine();
142137

143138
CLI::write('Documentation:', 'yellow');
144-
CLI::write(' https://frankenphp.dev/docs/worker/', 'blue');
139+
CLI::write(' https://frankenphp.dev/docs/worker/', 'blue');
145140
CLI::newLine();
146141
}
147142
}

system/Database/Config.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
use CodeIgniter\Config\BaseConfig;
1717
use CodeIgniter\Exceptions\InvalidArgumentException;
1818
use Config\Database as DbConfig;
19-
use Config\WorkerMode;
2019

2120
/**
2221
* @see \CodeIgniter\Database\ConfigTest

system/Session/Handlers/RedisHandler.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -305,10 +305,8 @@ public function close(): bool
305305
try {
306306
$pingReply = $this->redis->ping();
307307

308-
if (in_array($pingReply, [true, '+PONG'], true)) {
309-
if (isset($this->lockKey) && ! $this->releaseLock()) {
310-
return false;
311-
}
308+
if (in_array($pingReply, [true, '+PONG'], true) && (isset($this->lockKey) && ! $this->releaseLock())) {
309+
return false;
312310
}
313311
} catch (RedisException $e) {
314312
$this->logger->error('Session: Got RedisException on close(): ' . $e->getMessage());

system/Session/PersistsConnection.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ protected function hasPersistentConnection(): bool
5151

5252
/**
5353
* Get the persistent connection for this configuration.
54-
*
55-
* @return object|null
5654
*/
5755
protected function getPersistentConnection(): ?object
5856
{
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of CodeIgniter 4 framework.
7+
*
8+
* (c) CodeIgniter Foundation <admin@codeigniter.com>
9+
*
10+
* For the full copyright and license information, please view
11+
* the LICENSE file that was distributed with this source code.
12+
*/
13+
14+
namespace CodeIgniter\Commands;
15+
16+
use CodeIgniter\Test\CIUnitTestCase;
17+
use CodeIgniter\Test\StreamFilterTrait;
18+
use PHPUnit\Framework\Attributes\Group;
19+
20+
/**
21+
* @internal
22+
*/
23+
#[Group('Others')]
24+
final class WorkerCommandsTest extends CIUnitTestCase
25+
{
26+
use StreamFilterTrait;
27+
28+
/**
29+
* @var list<string>
30+
*/
31+
private array $filesToCleanup = [
32+
'public/frankenphp-worker.php',
33+
'Caddyfile',
34+
];
35+
36+
protected function tearDown(): void
37+
{
38+
parent::tearDown();
39+
40+
$this->cleanupFiles();
41+
}
42+
43+
private function cleanupFiles(): void
44+
{
45+
foreach ($this->filesToCleanup as $file) {
46+
$path = ROOTPATH . $file;
47+
if (is_file($path)) {
48+
@unlink($path);
49+
}
50+
}
51+
}
52+
53+
public function testWorkerInstallCreatesFiles(): void
54+
{
55+
command('worker:install');
56+
57+
$this->assertFileExists(ROOTPATH . 'public/frankenphp-worker.php');
58+
$this->assertFileExists(ROOTPATH . 'Caddyfile');
59+
60+
$output = $this->getStreamFilterBuffer();
61+
$this->assertStringContainsString('Worker mode files created successfully!', $output);
62+
$this->assertStringContainsString('File created:', $output);
63+
}
64+
65+
public function testWorkerInstallSkipsExistingFilesWithoutForce(): void
66+
{
67+
command('worker:install');
68+
$this->resetStreamFilterBuffer();
69+
70+
command('worker:install');
71+
72+
$output = $this->getStreamFilterBuffer();
73+
$this->assertStringContainsString('Worker mode files already exist', $output);
74+
$this->assertStringContainsString('Use --force to overwrite', $output);
75+
}
76+
77+
public function testWorkerInstallOverwritesWithForce(): void
78+
{
79+
command('worker:install');
80+
81+
$workerFile = ROOTPATH . 'public/frankenphp-worker.php';
82+
file_put_contents($workerFile, '<?php // Modified content');
83+
84+
$this->resetStreamFilterBuffer();
85+
86+
command('worker:install --force');
87+
88+
$output = $this->getStreamFilterBuffer();
89+
$this->assertStringContainsString('File overwritten:', $output);
90+
91+
$content = file_get_contents($workerFile);
92+
$this->assertStringNotContainsString('// Modified content', (string) $content);
93+
$this->assertStringContainsString('FrankenPHP Worker', (string) $content);
94+
}
95+
96+
public function testWorkerInstallShowsNextSteps(): void
97+
{
98+
command('worker:install');
99+
100+
$output = $this->getStreamFilterBuffer();
101+
$this->assertStringContainsString('Next Steps:', $output);
102+
$this->assertStringContainsString('frankenphp run', $output);
103+
$this->assertStringContainsString('https://frankenphp.dev/docs/worker/', $output);
104+
}
105+
106+
public function testWorkerUninstallRemovesFiles(): void
107+
{
108+
command('worker:install');
109+
$this->resetStreamFilterBuffer();
110+
111+
command('worker:uninstall --force');
112+
113+
$this->assertFileDoesNotExist(ROOTPATH . 'public/frankenphp-worker.php');
114+
$this->assertFileDoesNotExist(ROOTPATH . 'Caddyfile');
115+
116+
$output = $this->getStreamFilterBuffer();
117+
$this->assertStringContainsString('Worker mode files removed successfully!', $output);
118+
$this->assertStringContainsString('File removed:', $output);
119+
}
120+
121+
public function testWorkerUninstallWithNoFilesToRemove(): void
122+
{
123+
$this->cleanupFiles();
124+
125+
command('worker:uninstall --force');
126+
127+
$output = $this->getStreamFilterBuffer();
128+
$this->assertStringContainsString('No worker mode files found to remove', $output);
129+
}
130+
131+
public function testWorkerUninstallListsFilesToRemove(): void
132+
{
133+
command('worker:install');
134+
$this->resetStreamFilterBuffer();
135+
136+
command('worker:uninstall --force');
137+
138+
$output = $this->getStreamFilterBuffer();
139+
$this->assertStringContainsString('The following files will be removed:', $output);
140+
$this->assertStringContainsString('public/frankenphp-worker.php', $output);
141+
$this->assertStringContainsString('Caddyfile', $output);
142+
}
143+
144+
public function testWorkerInstallAndUninstallCycle(): void
145+
{
146+
command('worker:install');
147+
$this->assertFileExists(ROOTPATH . 'public/frankenphp-worker.php');
148+
$this->assertFileExists(ROOTPATH . 'Caddyfile');
149+
150+
command('worker:uninstall --force');
151+
$this->assertFileDoesNotExist(ROOTPATH . 'public/frankenphp-worker.php');
152+
$this->assertFileDoesNotExist(ROOTPATH . 'Caddyfile');
153+
}
154+
155+
public function testWorkerInstallCreatesValidPHPFile(): void
156+
{
157+
command('worker:install');
158+
159+
$workerFile = ROOTPATH . 'public/frankenphp-worker.php';
160+
$this->assertFileExists($workerFile);
161+
162+
$content = file_get_contents($workerFile);
163+
$this->assertStringStartsWith('<?php', $content);
164+
165+
$this->assertStringContainsString('frankenphp_handle_request', (string) $content);
166+
$this->assertStringContainsString('DatabaseConfig::validateForWorkerMode', (string) $content);
167+
$this->assertStringContainsString('DatabaseConfig::cleanupForWorkerMode', (string) $content);
168+
}
169+
170+
public function testWorkerInstallCreatesValidCaddyfile(): void
171+
{
172+
command('worker:install');
173+
174+
$caddyfile = ROOTPATH . 'Caddyfile';
175+
$this->assertFileExists($caddyfile);
176+
177+
$content = file_get_contents($caddyfile);
178+
179+
$this->assertStringContainsString('frankenphp', (string) $content);
180+
$this->assertStringContainsString('worker', (string) $content);
181+
$this->assertStringContainsString('public/frankenphp-worker.php', (string) $content);
182+
}
183+
}

tests/system/Database/ConfigTest.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
use CodeIgniter\Database\Postgre\Connection as PostgreConnection;
1717
use CodeIgniter\Test\CIUnitTestCase;
1818
use CodeIgniter\Test\ReflectionHelper;
19-
use Config\WorkerMode;
2019
use PHPUnit\Framework\Attributes\DataProvider;
2120
use PHPUnit\Framework\Attributes\Group;
2221

@@ -250,7 +249,7 @@ public function testResetForWorkerMode(): void
250249
$conn->transStart();
251250
$this->assertGreaterThan(0, $conn->transDepth);
252251

253-
Config::resetForWorkerMode();
252+
Config::cleanupForWorkerMode();
254253

255254
$this->assertSame(0, $conn->transDepth);
256255
$this->assertNotFalse($this->getPrivateProperty($conn, 'connID'));
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of CodeIgniter 4 framework.
7+
*
8+
* (c) CodeIgniter Foundation <admin@codeigniter.com>
9+
*
10+
* For the full copyright and license information, please view
11+
* the LICENSE file that was distributed with this source code.
12+
*/
13+
14+
namespace CodeIgniter\Database\Live;
15+
16+
use CodeIgniter\Test\CIUnitTestCase;
17+
use CodeIgniter\Test\DatabaseTestTrait;
18+
use PHPUnit\Framework\Attributes\Group;
19+
20+
/**
21+
* @internal
22+
*/
23+
#[Group('DatabaseLive')]
24+
final class PingTest extends CIUnitTestCase
25+
{
26+
use DatabaseTestTrait;
27+
28+
protected $migrate = false;
29+
30+
public function testPingReturnsTrueWhenConnected(): void
31+
{
32+
$this->db->initialize();
33+
34+
$result = $this->db->ping();
35+
36+
$this->assertTrue($result);
37+
}
38+
39+
public function testPingReturnsFalseWhenNotConnected(): void
40+
{
41+
$this->db->close();
42+
43+
$this->setPrivateProperty($this->db, 'connID', false);
44+
45+
$result = $this->db->ping();
46+
47+
$this->assertFalse($result);
48+
}
49+
50+
public function testPingAfterReconnect(): void
51+
{
52+
$this->db->close();
53+
$this->db->reconnect();
54+
55+
$result = $this->db->ping();
56+
57+
$this->assertTrue($result);
58+
}
59+
60+
public function testPingCanBeUsedToCheckConnectionBeforeQuery(): void
61+
{
62+
if ($this->db->ping()) {
63+
$result = $this->db->query('SELECT 1');
64+
$this->assertNotFalse($result);
65+
} else {
66+
$this->fail('Connection should be alive');
67+
}
68+
}
69+
}

tests/system/Events/EventsTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ public function testResetForWorkerMode(): void
341341
$performanceLog = Events::getPerformanceLogs();
342342
$this->assertNotEmpty($performanceLog);
343343

344-
Events::resetForWorkerMode();
344+
Events::cleanupForWorkerMode();
345345

346346
$performanceLog = Events::getPerformanceLogs();
347347
$this->assertEmpty($performanceLog);

0 commit comments

Comments
 (0)