Proof of concept - Vue Polling - Performance Improvement and tweaking for better user experience

This commit is contained in:
Dillon Ngo
2024-01-03 05:39:43 +08:00
parent f0ef9a5602
commit f54aae5dc9
5 changed files with 28 additions and 9 deletions
@@ -2,6 +2,7 @@
namespace App\Classes\Modules\Jobs\Processors; namespace App\Classes\Modules\Jobs\Processors;
use App\Classes\Exceptions\JobResourceNotFoundException;
use App\Classes\Modules\Jobs\Services\FetchesJobResult; use App\Classes\Modules\Jobs\Services\FetchesJobResult;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@@ -32,12 +33,15 @@ class FetchesJobResultProcessor
public function execute(Request $request){ public function execute(Request $request){
$res1 = $this->fetchesJobResult->execute(['job_id' => $request->route('job_id')]); $res1 = $this->fetchesJobResult->execute(['job_id' => $request->route('job_id')]);
if($request->route('is_last')){
if(!$res1->result){
$res2 = $this->fetchesJobResult->execute(['request_signature' => $res1->request_signature, 'result_not_null' => true, 'order_by_id_desc' => true]); $res2 = $this->fetchesJobResult->execute(['request_signature' => $res1->request_signature, 'result_not_null' => true, 'order_by_id_desc' => true]);
return $res2; return $res2;
} }
if(!$res1->result){
throw new JobResourceNotFoundException('Unable to find any job based on the criteria provided');
}
return $res1; return $res1;
} }
} }
@@ -44,9 +44,9 @@ class UpdateJobResultProcessor
try{ try{
$jobResultExisting = $this->fetchesJobResult->execute(['request_signature' => $jobResultCurrent->request_signature, 'result_not_null' => true, 'order_by_id_desc' => true]); $jobResultExisting = $this->fetchesJobResult->execute(['request_signature' => $jobResultCurrent->request_signature, 'result_not_null' => true, 'order_by_id_desc' => true]);
$resultSignatureExisting = $jobResultExisting->result_signature; $resultSignatureExisting = $jobResultExisting->result_signature;
if($resultSignatureExisting != $resultSignatureCurrent){ //if($resultSignatureExisting != $resultSignatureCurrent){
$this->updateJobResult($jobResultCurrent, $resultCurrentJson, $resultSignatureCurrent, $listGenericJobObject->getJobCommandName(), $listGenericJobObject->getJobCommand()); $this->updateJobResult($jobResultCurrent, $resultCurrentJson, $resultSignatureCurrent, $listGenericJobObject->getJobCommandName(), $listGenericJobObject->getJobCommand());
} //}
} catch (JobResourceNotFoundException $exception){ } catch (JobResourceNotFoundException $exception){
$this->updateJobResult($jobResultCurrent, $resultCurrentJson, $resultSignatureCurrent, $listGenericJobObject->getJobCommandName(), $listGenericJobObject->getJobCommand()); $this->updateJobResult($jobResultCurrent, $resultCurrentJson, $resultSignatureCurrent, $listGenericJobObject->getJobCommandName(), $listGenericJobObject->getJobCommand());
} }
Vendored
+2 -1
View File
@@ -37,6 +37,7 @@ gulp.task('vendorCss', () => {
.pipe(plugins.cleanCss()) .pipe(plugins.cleanCss())
.pipe(plugins.replace('../../../font-awesome/', './')) .pipe(plugins.replace('../../../font-awesome/', './'))
.pipe(plugins.replace('../../jquery-ui-dist/', '')) .pipe(plugins.replace('../../jquery-ui-dist/', ''))
//.pipe(plugins.replace(/background-image:url\(\.\.\/\.\./g, `background-image:url(`)) //cief todo: gulp
.pipe(gulp.dest(pkg.paths.build.css)); .pipe(gulp.dest(pkg.paths.build.css));
}); });
@@ -115,4 +116,4 @@ gulp.task('watch', (done) => {
gulp.watch(pkg.globs.sourceJs, gulp.series('sourceJs')); gulp.watch(pkg.globs.sourceJs, gulp.series('sourceJs'));
gulp.watch(pkg.globs.sourceJs, gulp.series('sourceFonts')); gulp.watch(pkg.globs.sourceJs, gulp.series('sourceFonts'));
done(); done();
}); });
@@ -126,8 +126,10 @@
errorHandler(error){ errorHandler(error){
this.isPolling = false; this.isPolling = false;
}, },
startPolling(jobId, maxAttempts = 4) { startPolling(jobId, maxAttempts = 8) {
let attempts = 0; let attempts = 0;
let interval = 15000; // Initial interval
const pollJobResult = () => { const pollJobResult = () => {
if (this.isPolling) { if (this.isPolling) {
return; return;
@@ -135,6 +137,9 @@
this.isPolling = true; this.isPolling = true;
attempts++; attempts++;
if(attempts === 1){
interval = 5000;
}
if (attempts > maxAttempts) { if (attempts > maxAttempts) {
clearInterval(this.pollingInterval); clearInterval(this.pollingInterval);
@@ -145,11 +150,16 @@
return; return;
} }
this.fetchJobResult(jobId); if(attempts === maxAttempts){
this.fetchJobResult(jobId, true);
}
else{
this.fetchJobResult(jobId);
}
}; };
// pollJobResult(); // Initial call // pollJobResult(); // Initial call
this.pollingInterval = setInterval(pollJobResult, 15000); this.pollingInterval = setInterval(pollJobResult, interval);
}, },
stopPolling() { stopPolling() {
clearInterval(this.pollingInterval); clearInterval(this.pollingInterval);
@@ -172,9 +182,12 @@
console.error('Error submitJob', error); console.error('Error submitJob', error);
} }
}, },
fetchJobResult(jobId) { fetchJobResult(jobId, isLastAttempt = false) {
try { try {
let anotherEndpoint = route('api.job.fetch', jobId); let anotherEndpoint = route('api.job.fetch', jobId);
if(isLastAttempt){
anotherEndpoint = route('api.job.fetch.last.attempt', jobId, isLastAttempt);
}
this.poll(anotherEndpoint, 'get', this.section, false, false); //cief todo: Uncaught (in promise) null this.poll(anotherEndpoint, 'get', this.section, false, false); //cief todo: Uncaught (in promise) null
} catch (error) { } catch (error) {
console.error('Error fetchJobResult', error); console.error('Error fetchJobResult', error);
+1
View File
@@ -4,4 +4,5 @@ use Illuminate\Support\Facades\Route;
Route::group(['prefix' => 'job', 'as' => 'job.', 'namespace' => 'Jobs'], function () { Route::group(['prefix' => 'job', 'as' => 'job.', 'namespace' => 'Jobs'], function () {
Route::get('/fetch/{job_id}', 'FetchJobResultController@fetch')->name('fetch'); Route::get('/fetch/{job_id}', 'FetchJobResultController@fetch')->name('fetch');
Route::get('/fetch/{job_id}/{is_last}', 'FetchJobResultController@fetch')->name('fetch.last.attempt');
}); });