Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
312
src/Framework/AsyncExamples/Assets/AsyncAssetProcessor.php
Normal file
312
src/Framework/AsyncExamples/Assets/AsyncAssetProcessor.php
Normal file
@@ -0,0 +1,312 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\AsyncExamples\Assets;
|
||||
|
||||
use App\Framework\Async\FiberManager;
|
||||
use App\Framework\Filesystem\Storage;
|
||||
|
||||
/**
|
||||
* Asynchroner Asset-Processor für CSS, JS und Bilder
|
||||
*/
|
||||
final class AsyncAssetProcessor
|
||||
{
|
||||
public function __construct(
|
||||
private readonly Storage $storage,
|
||||
private readonly FiberManager $fiberManager = new FiberManager(),
|
||||
private readonly array $config = []
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verarbeitet alle Assets parallel
|
||||
*/
|
||||
public function processAll(string $sourceDir, string $outputDir): array
|
||||
{
|
||||
$operations = [
|
||||
'css' => fn () => $this->processCss($sourceDir . '/css', $outputDir . '/css'),
|
||||
'js' => fn () => $this->processJs($sourceDir . '/js', $outputDir . '/js'),
|
||||
'images' => fn () => $this->processImages($sourceDir . '/images', $outputDir . '/images'),
|
||||
];
|
||||
|
||||
return $this->fiberManager->batch($operations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verarbeitet CSS-Dateien
|
||||
*/
|
||||
public function processCss(string $sourceDir, string $outputDir): array
|
||||
{
|
||||
$cssFiles = $this->findFiles($sourceDir, '*.css');
|
||||
$scssFiles = $this->findFiles($sourceDir, '*.scss');
|
||||
|
||||
$operations = [];
|
||||
|
||||
// Verarbeite CSS-Dateien
|
||||
foreach ($cssFiles as $file) {
|
||||
$operations["css_{$file}"] = fn () => $this->minifyCss($sourceDir . '/' . $file, $outputDir);
|
||||
}
|
||||
|
||||
// Verarbeite SCSS-Dateien
|
||||
foreach ($scssFiles as $file) {
|
||||
$operations["scss_{$file}"] = fn () => $this->compileSass($sourceDir . '/' . $file, $outputDir);
|
||||
}
|
||||
|
||||
return $this->fiberManager->batch($operations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verarbeitet JavaScript-Dateien
|
||||
*/
|
||||
public function processJs(string $sourceDir, string $outputDir): array
|
||||
{
|
||||
$jsFiles = $this->findFiles($sourceDir, '*.js');
|
||||
|
||||
$operations = [];
|
||||
foreach ($jsFiles as $file) {
|
||||
$operations["js_{$file}"] = fn () => $this->minifyJs($sourceDir . '/' . $file, $outputDir);
|
||||
}
|
||||
|
||||
return $this->fiberManager->batch($operations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verarbeitet Bilder
|
||||
*/
|
||||
public function processImages(string $sourceDir, string $outputDir): array
|
||||
{
|
||||
$imageFiles = array_merge(
|
||||
$this->findFiles($sourceDir, '*.jpg'),
|
||||
$this->findFiles($sourceDir, '*.jpeg'),
|
||||
$this->findFiles($sourceDir, '*.png'),
|
||||
$this->findFiles($sourceDir, '*.gif'),
|
||||
$this->findFiles($sourceDir, '*.svg')
|
||||
);
|
||||
|
||||
$operations = [];
|
||||
foreach ($imageFiles as $file) {
|
||||
$operations["img_{$file}"] = fn () => $this->optimizeImage($sourceDir . '/' . $file, $outputDir);
|
||||
}
|
||||
|
||||
return $this->fiberManager->batch($operations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bündelt JavaScript-Dateien
|
||||
*/
|
||||
public function bundleJs(array $files, string $outputFile): string
|
||||
{
|
||||
$operations = [];
|
||||
foreach ($files as $file) {
|
||||
$operations[$file] = fn () => $this->storage->get($file);
|
||||
}
|
||||
|
||||
$contents = $this->fiberManager->batch($operations);
|
||||
$bundled = implode("\n\n", array_filter($contents, fn ($c) => ! ($c instanceof \Throwable)));
|
||||
|
||||
$minified = $this->minifyJsContent($bundled);
|
||||
$this->storage->put($outputFile, $minified);
|
||||
|
||||
return $outputFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bündelt CSS-Dateien
|
||||
*/
|
||||
public function bundleCss(array $files, string $outputFile): string
|
||||
{
|
||||
$operations = [];
|
||||
foreach ($files as $file) {
|
||||
$operations[$file] = fn () => $this->storage->get($file);
|
||||
}
|
||||
|
||||
$contents = $this->fiberManager->batch($operations);
|
||||
$bundled = implode("\n\n", array_filter($contents, fn ($c) => ! ($c instanceof \Throwable)));
|
||||
|
||||
$minified = $this->minifyCssContent($bundled);
|
||||
$this->storage->put($outputFile, $minified);
|
||||
|
||||
return $outputFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generiert verschiedene Bildgrößen parallel
|
||||
*/
|
||||
public function generateImageSizes(string $sourceImage, array $sizes, string $outputDir): array
|
||||
{
|
||||
$operations = [];
|
||||
foreach ($sizes as $sizeName => $dimensions) {
|
||||
$operations[$sizeName] = fn () => $this->resizeImage(
|
||||
$sourceImage,
|
||||
$outputDir . '/' . $sizeName . '_' . basename($sourceImage),
|
||||
$dimensions['width'],
|
||||
$dimensions['height']
|
||||
);
|
||||
}
|
||||
|
||||
return $this->fiberManager->batch($operations);
|
||||
}
|
||||
|
||||
private function minifyCss(string $sourceFile, string $outputDir): string
|
||||
{
|
||||
$content = $this->storage->get($sourceFile);
|
||||
$minified = $this->minifyCssContent($content);
|
||||
|
||||
$outputFile = $outputDir . '/' . basename($sourceFile);
|
||||
$this->storage->put($outputFile, $minified);
|
||||
|
||||
return $outputFile;
|
||||
}
|
||||
|
||||
private function minifyCssContent(string $content): string
|
||||
{
|
||||
// Vereinfachte CSS-Minifizierung
|
||||
$content = preg_replace('/\s+/', ' ', $content);
|
||||
$content = str_replace(['; ', ' {', '{ ', ' }', '} ', ': '], [';', '{', '{', '}', '}', ':'], $content);
|
||||
$content = preg_replace('/\/\*.*?\*\//', '', $content);
|
||||
|
||||
return trim($content);
|
||||
}
|
||||
|
||||
private function compileSass(string $sourceFile, string $outputDir): string
|
||||
{
|
||||
// Vereinfachte SCSS-Kompilierung
|
||||
// In Produktion würde man eine echte SCSS-Library verwenden
|
||||
$content = $this->storage->get($sourceFile);
|
||||
|
||||
// Basis-Variable-Ersetzung
|
||||
$content = $this->processSassVariables($content);
|
||||
|
||||
$minified = $this->minifyCssContent($content);
|
||||
$outputFile = $outputDir . '/' . str_replace('.scss', '.css', basename($sourceFile));
|
||||
$this->storage->put($outputFile, $minified);
|
||||
|
||||
return $outputFile;
|
||||
}
|
||||
|
||||
private function minifyJs(string $sourceFile, string $outputDir): string
|
||||
{
|
||||
$content = $this->storage->get($sourceFile);
|
||||
$minified = $this->minifyJsContent($content);
|
||||
|
||||
$outputFile = $outputDir . '/' . basename($sourceFile);
|
||||
$this->storage->put($outputFile, $minified);
|
||||
|
||||
return $outputFile;
|
||||
}
|
||||
|
||||
private function minifyJsContent(string $content): string
|
||||
{
|
||||
// Vereinfachte JS-Minifizierung
|
||||
$content = preg_replace('/\s+/', ' ', $content);
|
||||
$content = str_replace(['; ', ' {', '{ ', ' }', '} '], [';', '{', '{', '}', '}'], $content);
|
||||
$content = preg_replace('/\/\*.*?\*\//', '', $content);
|
||||
$content = preg_replace('/\/\/.*$/m', '', $content);
|
||||
|
||||
return trim($content);
|
||||
}
|
||||
|
||||
private function optimizeImage(string $sourceFile, string $outputDir): string
|
||||
{
|
||||
// Vereinfachte Bildoptimierung
|
||||
// In Produktion würde man Bibliotheken wie Imagick verwenden
|
||||
$outputFile = $outputDir . '/' . basename($sourceFile);
|
||||
|
||||
// Kopiere erstmal nur
|
||||
$content = $this->storage->get($sourceFile);
|
||||
$this->storage->put($outputFile, $content);
|
||||
|
||||
return $outputFile;
|
||||
}
|
||||
|
||||
private function resizeImage(string $sourceFile, string $outputFile, int $width, int $height): string
|
||||
{
|
||||
// Vereinfachte Bildgrößenänderung
|
||||
// In Produktion würde man GD oder Imagick verwenden
|
||||
$content = $this->storage->get($sourceFile);
|
||||
$this->storage->put($outputFile, $content);
|
||||
|
||||
return $outputFile;
|
||||
}
|
||||
|
||||
private function processSassVariables(string $content): string
|
||||
{
|
||||
// Vereinfachte Variable-Verarbeitung
|
||||
preg_match_all('/\$([a-zA-Z0-9_-]+)\s*:\s*([^;]+);/', $content, $matches);
|
||||
|
||||
$variables = [];
|
||||
for ($i = 0; $i < count($matches[0]); $i++) {
|
||||
$variables['$' . $matches[1][$i]] = $matches[2][$i];
|
||||
}
|
||||
|
||||
foreach ($variables as $var => $value) {
|
||||
$content = str_replace($var, $value, $content);
|
||||
}
|
||||
|
||||
// Entferne Variable-Definitionen
|
||||
$content = preg_replace('/\$[a-zA-Z0-9_-]+\s*:\s*[^;]+;\s*/', '', $content);
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
private function findFiles(string $directory, string $pattern): array
|
||||
{
|
||||
if (! is_dir($directory)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$files = glob($directory . '/' . $pattern);
|
||||
|
||||
return array_map('basename', $files ?: []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Überwacht Dateien auf Änderungen und verarbeitet sie automatisch
|
||||
*/
|
||||
public function watch(string $sourceDir, string $outputDir): void
|
||||
{
|
||||
$this->fiberManager->async(function () use ($sourceDir, $outputDir) {
|
||||
$lastCheck = [];
|
||||
|
||||
while (true) {
|
||||
$files = array_merge(
|
||||
glob($sourceDir . '/**/*.css') ?: [],
|
||||
glob($sourceDir . '/**/*.scss') ?: [],
|
||||
glob($sourceDir . '/**/*.js') ?: []
|
||||
);
|
||||
|
||||
foreach ($files as $file) {
|
||||
$mtime = filemtime($file);
|
||||
if (! isset($lastCheck[$file]) || $lastCheck[$file] !== $mtime) {
|
||||
$this->processFile($file, $sourceDir, $outputDir);
|
||||
$lastCheck[$file] = $mtime;
|
||||
}
|
||||
}
|
||||
|
||||
sleep(1); // Prüfe jede Sekunde
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private function processFile(string $file, string $sourceDir, string $outputDir): void
|
||||
{
|
||||
$extension = pathinfo($file, PATHINFO_EXTENSION);
|
||||
$relativePath = str_replace($sourceDir . '/', '', $file);
|
||||
|
||||
switch ($extension) {
|
||||
case 'css':
|
||||
$this->minifyCss($file, dirname($outputDir . '/' . $relativePath));
|
||||
|
||||
break;
|
||||
case 'scss':
|
||||
$this->compileSass($file, dirname($outputDir . '/' . $relativePath));
|
||||
|
||||
break;
|
||||
case 'js':
|
||||
$this->minifyJs($file, dirname($outputDir . '/' . $relativePath));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user