Billie/app/Jobs/NodeJS/UnzipZipFiles.php

113 lines
3.5 KiB
PHP
Raw Normal View History

2025-05-06 02:47:26 +00:00
<?php
2025-05-23 02:19:35 +00:00
namespace App\Jobs;
2025-05-06 02:47:26 +00:00
2025-05-23 02:19:35 +00:00
use App\Models\ExecutionStep;
use App\Models\Submission;
2025-05-06 02:47:26 +00:00
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
2025-05-23 02:19:35 +00:00
use Illuminate\Support\Facades\File;
2025-05-06 02:47:26 +00:00
use Illuminate\Support\Facades\Log;
use Symfony\Component\Process\Process;
class UnzipZipFiles implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $submission;
public $zipFileDir;
public $tempDir;
public $command;
/**
* Create a new job instance.
*/
public function __construct($submission, $zipFileDir, $tempDir, $command)
{
$this->submission = $submission;
$this->zipFileDir = $zipFileDir;
$this->tempDir = $tempDir;
$this->command = $command;
}
/**
* Execute the job.
*/
public function handle(): void
{
$submission = $this->submission;
2025-05-06 03:25:09 +00:00
2025-05-06 02:47:26 +00:00
Log::info("Unzipping {$this->zipFileDir} into {$this->tempDir}");
$this->updateSubmissionStatus($submission, Submission::$PROCESSING, "Unzipping submitted folder");
2025-05-06 03:25:09 +00:00
2025-05-06 02:47:26 +00:00
try {
2025-05-06 03:25:09 +00:00
$this->prepareTempDirectory();
$process = new Process(
$this->command,
null,
$this->getEnvironment(),
null,
300
);
2025-05-06 02:47:26 +00:00
$process->start();
$process_pid = $process->getPid();
$process->wait();
if ($process->isSuccessful()) {
Log::info("Unzipped {$this->zipFileDir} into {$this->tempDir}");
$this->updateSubmissionStatus($submission, Submission::$COMPLETED, "Unzipped submitted folder");
} else {
2025-05-06 03:25:09 +00:00
$error = "Failed to unzip: " . $process->getErrorOutput() . "\n" . $process->getOutput();
Log::error($error);
$this->cleanup();
$this->updateSubmissionStatus($submission, Submission::$FAILED, $error);
}
} catch (\Throwable $th) {
$error = "Failed to unzip {$this->zipFileDir} " . $th->getMessage();
Log::error($error);
$this->cleanup();
$this->updateSubmissionStatus($submission, Submission::$FAILED, $error);
Process::fromShellCommandline('kill ' . $process_pid)->run();
Process::fromShellCommandline("rm -rf {$this->tempDir}")->run();
}
}
protected function prepareTempDirectory(): void
{
File::ensureDirectoryExists($this->tempDir, 0755);
File::cleanDirectory($this->tempDir);
}
protected function getEnvironment(): array
{
return [
'PATH' => '/usr/local/bin:/usr/bin:/bin:' . getenv('PATH'),
'HOME' => getenv('HOME') ?: '/tmp',
];
}
protected function cleanup(): void
{
try {
if (File::exists($this->tempDir)) {
File::deleteDirectory($this->tempDir);
2025-05-06 02:47:26 +00:00
}
} catch (\Throwable $th) {
2025-05-06 03:25:09 +00:00
Log::error("Cleanup failed: " . $th->getMessage());
2025-05-06 02:47:26 +00:00
}
}
private function updateSubmissionStatus(Submission $submission, string $status, string $output): void
{
$stepName = ExecutionStep::$UNZIP_ZIP_FILES;
2025-05-06 03:25:09 +00:00
if ($status !== Submission::$PROCESSING) {
$submission->updateOneResult($stepName, $status, $output);
}
if ($status !== Submission::$COMPLETED) {
$submission->updateStatus($status);
}
2025-05-06 02:47:26 +00:00
}
}