Skip to content

Commit 64651a0

Browse files
authored
Fix #115 - buffer each StreamedResponse chunk when sending data to swoole worker output (#116)
* Fix #115 - buffer each `StreamedResponse` chunk when sending data to swoole worker output This change ensures that, when converting a `StreamedResponse` to output within `php-runtime/swoole`, the output is streamed chunk-by-chunk, instead of being buffered in its entirety, and then being sent out to the swooler server all in one shot. This should fix some obvious performance, latency and memory issues related to streaming common responses assembled by PHP-side processes. Note: you will still need to disable symfony's `StreamedResponseListener` when working with this package. Ref: #115 * Disabled error handler replacement, which is implicitly done by the `GenericRuntime` We don't want to replace the error handler: PHPUnit is good enough. This should bring the tests back to green too. * Upgrade PHPUnit configuration to comply with latest `phpunit.xsd` Ref: https://github.com/sebastianbergmann/phpunit/blob/f61e897412fe831831462c0698a6208f7d8298f0/phpunit.xsd#L255 Ref: https://github.com/sebastianbergmann/phpunit/blob/f61e897412fe831831462c0698a6208f7d8298f0/phpunit.xsd#L16-L20
1 parent 10e08e8 commit 64651a0

File tree

4 files changed

+28
-9
lines changed

4 files changed

+28
-9
lines changed

phpunit.xml.dist

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
<directory>./tests/Unit</directory>
1616
</testsuite>
1717
</testsuites>
18-
<filter>
19-
<whitelist processUncoveredFilesFromWhitelist="true">
18+
<coverage>
19+
<include>
2020
<directory suffix=".php">src</directory>
21-
</whitelist>
22-
</filter>
21+
</include>
22+
</coverage>
2323
</phpunit>

src/SymfonyHttpBridge.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public static function reflectSymfonyResponse(SymfonyResponse $sfResponse, Respo
5050
$response->write($buffer);
5151

5252
return '';
53-
});
53+
}, 4096);
5454
$sfResponse->sendContent();
5555
ob_end_clean();
5656
$response->end();

tests/Unit/RuntimeTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class RuntimeTest extends TestCase
1515
{
1616
public function testGetRunnerCreatesARunnerForCallbacks(): void
1717
{
18-
$options = [];
18+
$options = ['error_handler' => false];
1919
$runtime = new Runtime($options);
2020

2121
$application = static function (): void {
@@ -27,7 +27,7 @@ public function testGetRunnerCreatesARunnerForCallbacks(): void
2727

2828
public function testGetRunnerCreatesARunnerForSymfony(): void
2929
{
30-
$options = [];
30+
$options = ['error_handler' => false];
3131
$runtime = new Runtime($options);
3232

3333
$application = $this->createMock(HttpKernelInterface::class);
@@ -38,7 +38,7 @@ public function testGetRunnerCreatesARunnerForSymfony(): void
3838

3939
public function testGetRunnerCreatesARunnerForLaravel(): void
4040
{
41-
$options = [];
41+
$options = ['error_handler' => false];
4242
$runtime = new Runtime($options);
4343

4444
$application = $this->createMock(Kernel::class);
@@ -49,7 +49,7 @@ public function testGetRunnerCreatesARunnerForLaravel(): void
4949

5050
public function testGetRunnerFallbacksToClosureRunner(): void
5151
{
52-
$options = [];
52+
$options = ['error_handler' => false];
5353
$runtime = new Runtime($options);
5454

5555
$runner = $runtime->getRunner(null);

tests/Unit/SymfonyHttpBridgeTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,23 @@ public function testThatSymfonyBinaryFileResponseWithRangeIsReflected(): void
129129

130130
SymfonyHttpBridge::reflectSymfonyResponse($sfResponse, $response);
131131
}
132+
133+
public function testStreamedResponseWillRespondWithOneChunkAtATime(): void
134+
{
135+
$sfResponse = new StreamedResponse(static function () {
136+
echo str_repeat('a', 4096);
137+
echo str_repeat('b', 4095);
138+
});
139+
140+
$response = $this->createMock(Response::class);
141+
$response->expects(self::exactly(2))
142+
->method('write')
143+
->with(self::logicalOr(
144+
str_repeat('a', 4096),
145+
str_repeat('b', 4095)
146+
));
147+
$response->expects(self::once())->method('end');
148+
149+
SymfonyHttpBridge::reflectSymfonyResponse($sfResponse, $response);
150+
}
132151
}

0 commit comments

Comments
 (0)