- upload recording of call in chunks - recordings are merged on server side in jobs - improve UI of the recording tab
99 lines
2.9 KiB
PHP
99 lines
2.9 KiB
PHP
<?php
|
|
|
|
namespace App\Jobs;
|
|
|
|
use App\Actions\Interview\MergeRecordingChunksAction;
|
|
use App\Models\Interview;
|
|
use Illuminate\Bus\Queueable;
|
|
use Illuminate\Contracts\Queue\ShouldBeUnique;
|
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
use Illuminate\Foundation\Bus\Dispatchable;
|
|
use Illuminate\Queue\Attributes\Backoff;
|
|
use Illuminate\Queue\Attributes\Timeout;
|
|
use Illuminate\Queue\Attributes\Tries;
|
|
use Illuminate\Queue\Attributes\UniqueFor;
|
|
use Illuminate\Queue\Attributes\WithoutRelations;
|
|
use Illuminate\Queue\InteractsWithQueue;
|
|
use Illuminate\Queue\SerializesModels;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Throwable;
|
|
|
|
#[Timeout(300)]
|
|
#[Tries(3)]
|
|
#[Backoff(5, 15, 30)]
|
|
#[UniqueFor(1800)]
|
|
#[WithoutRelations]
|
|
class MergeRecordingChunksJob implements ShouldQueue, ShouldBeUnique
|
|
{
|
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
|
|
|
/**
|
|
* Create a new job instance.
|
|
*
|
|
* @param int|string $interviewId
|
|
* @param string $sessionId
|
|
* @param string|null $tempDir
|
|
* @param string|null $folderName
|
|
* @param int $totalChunks
|
|
* @param int|null $duration
|
|
*/
|
|
public function __construct(
|
|
public int|string $interviewId,
|
|
public string $sessionId,
|
|
public ?string $tempDir = null,
|
|
public ?string $folderName = null,
|
|
public int $totalChunks = 0,
|
|
public ?int $duration = null
|
|
) {}
|
|
|
|
/**
|
|
* The unique ID of the job.
|
|
*/
|
|
public function uniqueId(): string
|
|
{
|
|
return 'merge_rec_' . $this->interviewId . '_' . $this->sessionId;
|
|
}
|
|
|
|
/**
|
|
* Execute the job.
|
|
*/
|
|
public function handle(MergeRecordingChunksAction $mergeAction): void
|
|
{
|
|
Cache::lock('interview_merge_lock_' . $this->interviewId, 60)->block(15, function () use ($mergeAction) {
|
|
$interview = Interview::where('id', $this->interviewId)
|
|
->orWhere('submission_unique_id', $this->interviewId)
|
|
->first();
|
|
|
|
if (!$interview) {
|
|
Log::warning('[MergeRecordingChunksJob] Interview not found', [
|
|
'interview_id' => $this->interviewId,
|
|
'session_id' => $this->sessionId,
|
|
]);
|
|
return;
|
|
}
|
|
|
|
$mergeAction->execute(
|
|
$interview,
|
|
$this->sessionId,
|
|
$this->tempDir,
|
|
$this->folderName,
|
|
$this->duration
|
|
);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Handle a job failure.
|
|
*/
|
|
public function failed(?Throwable $exception): void
|
|
{
|
|
Log::error('[MergeRecordingChunksJob] Recording merge job failed', [
|
|
'interview_id' => $this->interviewId,
|
|
'session_id' => $this->sessionId,
|
|
'error' => $exception?->getMessage(),
|
|
'trace' => $exception?->getTraceAsString(),
|
|
]);
|
|
}
|
|
}
|