fix handle retry button
This commit is contained in:
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Api;
|
|||||||
|
|
||||||
use App\Enums\ImportDatasourceStatus;
|
use App\Enums\ImportDatasourceStatus;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Jobs\RetrySyncronizeJob;
|
||||||
use App\Jobs\ScrapingDataJob;
|
use App\Jobs\ScrapingDataJob;
|
||||||
use App\Jobs\SyncronizeSIMBG;
|
use App\Jobs\SyncronizeSIMBG;
|
||||||
use App\Models\ImportDatasource;
|
use App\Models\ImportDatasource;
|
||||||
@@ -37,35 +38,25 @@ class ScrapingController extends Controller
|
|||||||
return $this->resSuccess(["message" => "Success execute scraping service on background, check status for more"]);
|
return $this->resSuccess(["message" => "Success execute scraping service on background, check status for more"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function retry_syncjob(string $import_datasource_id){
|
||||||
* Store a newly created resource in storage.
|
try{
|
||||||
*/
|
|
||||||
public function store(Request $request)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
$import_datasource = ImportDatasource::find($import_datasource_id);
|
||||||
* Display the specified resource.
|
if(!$import_datasource){
|
||||||
*/
|
return $this->resError("Invalid import datasource id", null, 404);
|
||||||
public function show(string $id)
|
}
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
dispatch(new RetrySyncronizeJob($import_datasource->id));
|
||||||
* Update the specified resource in storage.
|
return response()->json([
|
||||||
*/
|
"success" => true,
|
||||||
public function update(Request $request, string $id)
|
"message" => "Retrying scrape job on background, check status for more"
|
||||||
{
|
]);
|
||||||
//
|
}catch(\Exception $e){
|
||||||
}
|
return response()->json([
|
||||||
|
"success" => false,
|
||||||
/**
|
"message" => "Failed to retry sync job",
|
||||||
* Remove the specified resource from storage.
|
"error" => $e->getMessage()
|
||||||
*/
|
]);
|
||||||
public function destroy(string $id)
|
}
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ class ImportDatasourceResource extends JsonResource
|
|||||||
"finish_time" => $finishTime ? $finishTime->toDateTimeString() : null,
|
"finish_time" => $finishTime ? $finishTime->toDateTimeString() : null,
|
||||||
"created_at" => $this->created_at->toDateTimeString(),
|
"created_at" => $this->created_at->toDateTimeString(),
|
||||||
"updated_at" => $this->updated_at->toDateTimeString(),
|
"updated_at" => $this->updated_at->toDateTimeString(),
|
||||||
|
"failed_uuid" => $this->failed_uuid
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
76
app/Jobs/RetrySyncronizeJob.php
Normal file
76
app/Jobs/RetrySyncronizeJob.php
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Jobs;
|
||||||
|
|
||||||
|
use App\Enums\ImportDatasourceStatus;
|
||||||
|
use App\Models\BigdataResume;
|
||||||
|
use App\Models\ImportDatasource;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Foundation\Queue\Queueable;
|
||||||
|
use App\Services\ServiceTabPbgTask;
|
||||||
|
use App\Services\ServiceGoogleSheet;
|
||||||
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
class RetrySyncronizeJob implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Queueable, Dispatchable, InteractsWithQueue, SerializesModels;
|
||||||
|
private $import_datasource_id;
|
||||||
|
public function __construct(int $import_datasource_id)
|
||||||
|
{
|
||||||
|
$this->import_datasource_id = $import_datasource_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the job.
|
||||||
|
*/
|
||||||
|
public function handle(): void
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
$service_tab_pbg_task = app(ServiceTabPbgTask::class);
|
||||||
|
$service_google_sheet = app(ServiceGoogleSheet::class);
|
||||||
|
|
||||||
|
$failed_import = ImportDatasource::find($this->import_datasource_id);
|
||||||
|
|
||||||
|
$failed_import->update([
|
||||||
|
'message' => "Retrying from UUID: ". $failed_import->failed_uuid,
|
||||||
|
'status' => ImportDatasourceStatus::Processing->value,
|
||||||
|
'start_time' => now()
|
||||||
|
]);
|
||||||
|
|
||||||
|
$current_failed_uuid = null;
|
||||||
|
try{
|
||||||
|
$service_tab_pbg_task->run_service($failed_import->failed_uuid);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
$current_failed_uuid = $service_tab_pbg_task->getFailedUUID();
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data_setting_result = $service_google_sheet->get_big_resume_data();
|
||||||
|
|
||||||
|
BigdataResume::generateResumeData($failed_import->id, "all", $data_setting_result);
|
||||||
|
BigdataResume::generateResumeData($failed_import->id, now()->year, $data_setting_result);
|
||||||
|
|
||||||
|
$failed_import->update([
|
||||||
|
'status' => ImportDatasourceStatus::Success->value,
|
||||||
|
'message' => "Retry completed successfully from UUID: ". $failed_import->failed_uuid,
|
||||||
|
'finish_time' => now(),
|
||||||
|
'failed_uuid' => null
|
||||||
|
]);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
\Log::error("RetrySyncronizeJob Failed: ". $e->getMessage(), [
|
||||||
|
'exception' => $e,
|
||||||
|
]);
|
||||||
|
if(isset($failed_import)){
|
||||||
|
$failed_import->update([
|
||||||
|
'status' => ImportDatasourceStatus::Failed->value,
|
||||||
|
'message' => "Retry failed from UUID: ". $failed_import->failed_uuid,
|
||||||
|
'finish_time' => now(),
|
||||||
|
'failed_uuid' => $current_failed_uuid
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->fail($e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -44,13 +44,21 @@ class ScrapingDataJob implements ShouldQueue
|
|||||||
'message' => 'Initiating scraping...',
|
'message' => 'Initiating scraping...',
|
||||||
'response_body' => null,
|
'response_body' => null,
|
||||||
'status' => 'processing',
|
'status' => 'processing',
|
||||||
'start_time' => now()
|
'start_time' => now(),
|
||||||
|
'failed_uuid' => null
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$failed_uuid = null;
|
||||||
|
|
||||||
// Run the scraping services
|
// Run the scraping services
|
||||||
$service_google_sheet->run_service();
|
$service_google_sheet->run_service();
|
||||||
$service_pbg_task->run_service();
|
$service_pbg_task->run_service();
|
||||||
$service_tab_pbg_task->run_service();
|
try{
|
||||||
|
$service_tab_pbg_task->run_service();
|
||||||
|
}catch(\Exception $e){
|
||||||
|
$failed_uuid = $service_tab_pbg_task->getFailedUUID();
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
$data_setting_result = $service_google_sheet->get_big_resume_data();
|
$data_setting_result = $service_google_sheet->get_big_resume_data();
|
||||||
|
|
||||||
@@ -72,7 +80,8 @@ class ScrapingDataJob implements ShouldQueue
|
|||||||
$import_datasource->update([
|
$import_datasource->update([
|
||||||
'status' => 'failed',
|
'status' => 'failed',
|
||||||
'response_body' => 'Error: ' . $e->getMessage(),
|
'response_body' => 'Error: ' . $e->getMessage(),
|
||||||
'finish_time' => now()
|
'finish_time' => now(),
|
||||||
|
'failed_uuid' => $failed_uuid,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -158,8 +158,6 @@ class ServicePbgTask
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::info("Page {$currentPage} fetched & saved", ['records' => count($saved_data)]);
|
|
||||||
|
|
||||||
$currentPage++;
|
$currentPage++;
|
||||||
} while ($currentPage <= $totalPage);
|
} while ($currentPage <= $totalPage);
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ class ServiceTabPbgTask
|
|||||||
private $service_token;
|
private $service_token;
|
||||||
private $user_token;
|
private $user_token;
|
||||||
private $user_refresh_token;
|
private $user_refresh_token;
|
||||||
|
protected $current_uuid = null;
|
||||||
|
|
||||||
public function __construct(Client $client, ServiceTokenSIMBG $service_token)
|
public function __construct(Client $client, ServiceTokenSIMBG $service_token)
|
||||||
{
|
{
|
||||||
@@ -34,25 +35,42 @@ class ServiceTabPbgTask
|
|||||||
$this->user_refresh_token = $auth_data['refresh'];
|
$this->user_refresh_token = $auth_data['refresh'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run_service()
|
public function run_service($retry_uuid = null)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$pbg_tasks = PbgTask::all();
|
$pbg_tasks = PbgTask::orderBy('id')->get();
|
||||||
|
$start = false;
|
||||||
|
|
||||||
foreach ($pbg_tasks as $pbg_task) {
|
foreach ($pbg_tasks as $pbg_task) {
|
||||||
$this->scraping_task_assignments($pbg_task->uuid);
|
if($retry_uuid){
|
||||||
$this->scraping_task_retributions($pbg_task->uuid);
|
if($pbg_task->uuid === $retry_uuid){
|
||||||
$this->scraping_task_integrations($pbg_task->uuid);
|
$start = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Process task assignments here if needed
|
if(!$start){
|
||||||
Log::info("Successfully fetched for UUID: {$pbg_task->uuid}");
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try{
|
||||||
|
$this->current_uuid = $pbg_task->uuid;
|
||||||
|
$this->scraping_task_assignments($pbg_task->uuid);
|
||||||
|
$this->scraping_task_retributions($pbg_task->uuid);
|
||||||
|
$this->scraping_task_integrations($pbg_task->uuid);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
Log::error("Failed on UUID: {$this->current_uuid}, Error: " . $e->getMessage());
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Log::error("Failed to scrape task assignments: " . $e->getMessage());
|
Log::error("Failed to syncronize: " . $e->getMessage());
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getFailedUUID(){
|
||||||
|
return $this->current_uuid;
|
||||||
|
}
|
||||||
|
|
||||||
private function scraping_task_assignments($uuid)
|
private function scraping_task_assignments($uuid)
|
||||||
{
|
{
|
||||||
$url = "{$this->simbg_host}/api/pbg/v1/list-tim-penilai/{$uuid}/?page=1&size=10";
|
$url = "{$this->simbg_host}/api/pbg/v1/list-tim-penilai/{$uuid}/?page=1&size=10";
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('import_datasources', function (Blueprint $table) {
|
||||||
|
$table->string('failed_uuid')->nullable()->after('status');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('import_datasources', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('failed_uuid');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -27,6 +27,7 @@ class BigdataResume {
|
|||||||
this.table = new Grid({
|
this.table = new Grid({
|
||||||
columns: [
|
columns: [
|
||||||
{ name: "ID" },
|
{ name: "ID" },
|
||||||
|
{ name: "Year" },
|
||||||
{ name: "Jumlah Potensi" },
|
{ name: "Jumlah Potensi" },
|
||||||
{ name: "Total Potensi" },
|
{ name: "Total Potensi" },
|
||||||
{ name: "Jumlah Berkas Belum Terverifikasi" },
|
{ name: "Jumlah Berkas Belum Terverifikasi" },
|
||||||
@@ -79,6 +80,7 @@ class BigdataResume {
|
|||||||
then: (data) => {
|
then: (data) => {
|
||||||
return data.data.map((item) => [
|
return data.data.map((item) => [
|
||||||
item.id,
|
item.id,
|
||||||
|
item.year,
|
||||||
item.potention_count,
|
item.potention_count,
|
||||||
addThousandSeparators(item.potention_sum),
|
addThousandSeparators(item.potention_sum),
|
||||||
item.non_verified_count,
|
item.non_verified_count,
|
||||||
|
|||||||
@@ -28,6 +28,19 @@ class SyncronizeTask {
|
|||||||
"Duration",
|
"Duration",
|
||||||
"Finished",
|
"Finished",
|
||||||
"Created",
|
"Created",
|
||||||
|
{
|
||||||
|
name: "Action",
|
||||||
|
formatter: (cell) => {
|
||||||
|
if (cell.status === "failed") {
|
||||||
|
return gridjs.html(`
|
||||||
|
<button data-id="${cell.id}" class="btn btn-sm btn-warning d-flex align-items-center gap-1 btn-retry">
|
||||||
|
<iconify-icon icon="mingcute:refresh-3-line" width="15" height="15"></iconify-icon>
|
||||||
|
<span>Retry</span>
|
||||||
|
</button>
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
search: {
|
search: {
|
||||||
server: {
|
server: {
|
||||||
@@ -62,10 +75,20 @@ class SyncronizeTask {
|
|||||||
item.duration,
|
item.duration,
|
||||||
item.finish_time,
|
item.finish_time,
|
||||||
item.created_at,
|
item.created_at,
|
||||||
|
item,
|
||||||
]),
|
]),
|
||||||
total: (data) => data.meta.total,
|
total: (data) => data.meta.total,
|
||||||
},
|
},
|
||||||
}).render(tableContainer);
|
}).render(tableContainer);
|
||||||
|
|
||||||
|
tableContainer.addEventListener("click", (event) => {
|
||||||
|
let btn = event.target.closest(".btn-retry");
|
||||||
|
if (btn) {
|
||||||
|
const id = btn.getAttribute("data-id");
|
||||||
|
btn.disabled = true;
|
||||||
|
this.handleRetrySync(id, btn);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
handleSubmitSync() {
|
handleSubmitSync() {
|
||||||
const button = document.getElementById("btn-sync-submit");
|
const button = document.getElementById("btn-sync-submit");
|
||||||
@@ -117,6 +140,48 @@ class SyncronizeTask {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleRetrySync(id, btn) {
|
||||||
|
const apiToken = document
|
||||||
|
.querySelector('meta[name="api-token"]')
|
||||||
|
.getAttribute("content");
|
||||||
|
|
||||||
|
fetch(`${GlobalConfig.apiHost}/api/retry-scraping/${id}`, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${apiToken}`,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(async (response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log("API Response:", data); // Debugging
|
||||||
|
|
||||||
|
// Show success message
|
||||||
|
const message =
|
||||||
|
data?.data?.message ||
|
||||||
|
data?.message ||
|
||||||
|
"Synchronization successful!";
|
||||||
|
this.toastMessage.innerText = message;
|
||||||
|
this.toast.show();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error("Fetch error:", err);
|
||||||
|
|
||||||
|
// Show error message
|
||||||
|
this.toastMessage.innerText =
|
||||||
|
err.message ||
|
||||||
|
"Failed to synchronize, something went wrong!";
|
||||||
|
this.toast.show();
|
||||||
|
|
||||||
|
// Re-enable button on failure
|
||||||
|
btn.disabled = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
handleSyncClick() {
|
handleSyncClick() {
|
||||||
const button = document.getElementById("btn-sync-submit");
|
const button = document.getElementById("btn-sync-submit");
|
||||||
const spinner = document.getElementById("spinner");
|
const spinner = document.getElementById("spinner");
|
||||||
|
|||||||
@@ -72,7 +72,11 @@ Route::group(['middleware' => 'auth:sanctum'], function (){
|
|||||||
});
|
});
|
||||||
|
|
||||||
// scraping
|
// scraping
|
||||||
Route::apiResource('/scraping', ScrapingController::class);
|
Route::controller(ScrapingController::class)->group(function (){
|
||||||
|
Route::get('/scraping','index')->name('scraping');
|
||||||
|
Route::get('/retry-scraping/{id}','retry_syncjob')->name('retry-scraping');
|
||||||
|
});
|
||||||
|
// Route::apiResource('/scraping', ScrapingController::class);
|
||||||
|
|
||||||
// reklame
|
// reklame
|
||||||
Route::apiResource('advertisements', AdvertisementController::class);
|
Route::apiResource('advertisements', AdvertisementController::class);
|
||||||
|
|||||||
Reference in New Issue
Block a user