I have code that POST's to a web service, and polls repeatedly after a small delay for a status update. To avoid monopolizing the browser's main thread, I want to put this code in a web worker. Had this been a straightforward Javascript only, I could figure this out. However, I'm running this in an Angular 6 environment. I can't upgrade to Angular 8 which supports web workers in the CLI, in large part due to dependency conflicts. Also, the service is written in Typescript and makes use of things like HttpClient from @angular/common/http that make the REST calls. Some pages talk about doing some separate WebPack, others use this ngx-web-worker library, most assume you're using the latest Angular.
I'm somewhat new to Angular and Node but don't want to do something ill-advised. Having said that, I need it to be reasonably simple and not require me to read 50 pages to figure out how to do it. I would have thought Angular solved this in V6 so I'm assuming there's an easy solution that I don't know of.
Below is the component from which I want to do the web worker. Please see method onChooseBlueReportFile():
import { Component, OnInit, Input } from '@angular/core';
import { reloadW3dsScript } from '../../../../shared/utils/w3ds.util';
import { SoftlayerService } from '../../../../core/services/softlayer.service';
import { SpringBatchJobExecutionStatus } from '../../../../shared/models/SpringBatchJobExecutionStatus';
@Component({
selector: 'app-report-uploader',
templateUrl: './report-uploader.component.html',
styleUrls: ['./report-uploader.component.css']
})
export class ReportUploaderComponent implements OnInit {
blueReportFile: File;
blueReportSelected = true;
blueReportFileName: string;
softLayerCostFilePercentUploaded: number = 0;
showLoaderBlueReport = false;
successBlueReport = false;
responseBlueReport = '';
stillProcessing: boolean = false;
errorBlueReport = false;
errorMessageBlueReport: string = '';
uploadErrorTitleBlueReport: string;
uploadErrorToDisplayBlueReport: any;
@Input() uploaderStatus: string = 'NOTHING_SELECTED';
constructor(private softlayerService: SoftlayerService) {
this.blueReportFileName = 'No file selected';
}
ngOnInit() {
}
ngAfterContentInit() {
reloadW3dsScript();
}
sleep(ms: number) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
async onChooseBlueReportFile(files: FileList) {
console.log('@@@ onChooseBlueReportFile');
this.blueReportSelected = true;
this.blueReportFileName = files.item(0).name;
this.blueReportFile = files.item(0);
const pattern = /\d*[0-9]+[.]+\d{3}[0-9]$/;
if (this.blueReportFileName == null || this.blueReportFileName == 'No file selected') {
this.uploaderStatus = 'ERROR';
this.displayUploadBlueReportsError('No file selected.Please select one.');
} else {
this.uploaderStatus = '';
this.errorBlueReport = false;
if (!this.errorBlueReport) {
this.showLoaderBlueReport = true;
(async () => {
this.softlayerService.postAsyncFiles(this.blueReportFile)
.subscribe(postAsyncFilesData => {
this.uploaderStatus = 'UPLOADING';
console.log('Post async cost file Received ' + postAsyncFilesData);
var errorDetected = false;
var jobExecutionResult: SpringBatchJobExecutionStatus = postAsyncFilesData;
var counter = 0;
console.log(JSON.stringify(jobExecutionResult));
if (jobExecutionResult.exitStatus === 'RUNNING' || jobExecutionResult.batchStatus === 'STARTING') {
console.log('Beginning jobExecutionResult fetch loop');
while (jobExecutionResult.batchStatus === 'RUNNING' || jobExecutionResult.batchStatus === 'STARTING' && counter < 10) {
counter++;
console.log('@@@ jobExecutionResult=' + JSON.stringify(jobExecutionResult));
this.showLoaderBlueReport = false;
this.stillProcessing = true;
//this.softLayerCostFilePercentUploaded = jobExecutionResult.percentComplete;
this.softLayerCostFilePercentUploaded += 10;
console.log('Before sleep');
this.sleep(10000);
console.log('After sleep');
this.softlayerService.getAsyncFiles(jobExecutionResult.jobInstanceId, jobExecutionResult.jobExecutionId).subscribe(
(getAsyncFilesData) => {
console.log('Got job execution status ' + JSON.stringify(getAsyncFilesData));
jobExecutionResult = getAsyncFilesData;
},
(error) => {
console.log('Error getting job execution status ' + error);
errorDetected = true;
this.uploaderStatus = 'ERROR';
this.showLoaderBlueReport = false;
this.displayUploadBlueReportsError(error, 'File upload failed');
}
);
console.log('After end jobExecutionResult fetch loop');
} /* end while */
console.log('After loop fetching status execution status ' + jobExecutionResult.exitStatus);
console.log('After loop fetching error ' + errorDetected);
} else {
console.log('Not entering check loop batchStatus='+jobExecutionResult.batchStatus+' exitStatus='+jobExecutionResult.exitStatus);
}
this.showLoaderBlueReport = false;
this.successBlueReport = true;
this.blueReportFileName = "No file selected";
this.blueReportSelected = false;
/** TODO Tap parent container for this function */
//this.getCurrentUserFiles();
},
(error) => {
this.uploaderStatus = 'ERROR';
this.showLoaderBlueReport = false;
this.displayUploadBlueReportsError(error, 'File upload failed');
});
}
)();
}
}
}
displayUploadBlueReportsError(error: any, title?: string) {
this.errorBlueReport = true;
this.responseBlueReport = '';
this.successBlueReport = false;
this.uploadErrorTitleBlueReport = title;
this.uploadErrorToDisplayBlueReport = error;
}
}
Thanks, Woodsman