I have this code
<?php
use Swoole\Coroutine;
use Swoole\Coroutine\System;
use Swoole\Coroutine\WaitGroup;
use Swoole\Http\Server as HttpServer;
use Swoole\Runtime;
Runtime::enableCoroutine(true);
ini_set('memory_limit', -1);
$server = new HttpServer('0.0.0.0', 9000);
$server->set([
'package_max_length' => 10000000,
]);
$server->on('start', function ($server) {
echo "Server started at http://localhost:9000\n";
});
const SIZES = [
[
'width' => 400,
'height' => 300,
'name' => '-tile',
],
[
'width' => 1080,
'height' => 720,
'name' => '-big-tile',
]
];
$server->on('request', function ($request, $response) {
if ($request->server['request_method'] === 'POST') {
$images = $request->files['images'];
$wg = new WaitGroup();
foreach ($images as $key => $image) {
$filename = pathinfo($image['name'], PATHINFO_FILENAME);
switch ($image['type']) {
case 'image/png':
$sourceImage = imagecreatefrompng($image['tmp_name']);
break;
case 'image/jpeg':
$sourceImage = imagecreatefromjpeg($image['tmp_name']);
break;
case 'image/webp':
$sourceImage = imagecreatefromwebp($image['tmp_name']);
break;
default:
throw new Exception('Unsupported image format: ' . $image['type']);
}
$wg->add();
$size = SIZES[0];
go(function () use ($wg, $key, $size, $sourceImage, $filename) {
echo "BEGIN: $key\n";
try {
$sourceWidth = imagesx($sourceImage);
$sourceHeight = imagesy($sourceImage);
$aspectRatio = $sourceWidth / $sourceHeight;
if ($aspectRatio > $size['width'] / $size['height']) {
$size['height'] = intval($size['width'] / $aspectRatio);
} else {
$size['width'] = intval($size['height'] * $aspectRatio);
}
$targetImage = imagescale($sourceImage, $size['width'], $size['height']);
// convert to WebP and save to file
ob_start();
imagewebp($targetImage, null, 100);
$webpImage = ob_get_clean();
System::writeFile("$filename.webp", $webpImage);
imagedestroy($sourceImage);
imagedestroy($targetImage);
echo "END: $key\n";
} catch (Exception $e) {
echo "Error processing image: $filename - " . $e->getMessage() . "\n";
}
$wg->done();
});
}
$wg->wait();
$response->header('Content-Type', 'text/plain');
$response->end("Images processed\n");
}
});
$server->start();
and output like this
BEGIN: 0
END: 0
BEGIN: 1
END: 1
BEGIN: 2
END: 2
BEGIN: 3
END: 3
BEGIN: 4
END: 4
BEGIN: 5
END: 5
BEGIN: 6
END: 6
BEGIN: 7
END: 7
How can I process images async? Because here it looks sync; it looks like it just add tasks to stack and processes them one by one, so there is no difference between this code with coroutines and without coroutines. The time of execution for 10 images was the same.
I was trying to use Swoole\Process but I can’t use them inside 'request'.