Skip to content

Commit 2d59306

Browse files
committed
support sending messages from worker
1 parent 64f3fc3 commit 2d59306

File tree

7 files changed

+59
-19
lines changed

7 files changed

+59
-19
lines changed

src/firefly/js/threadWorker/WorkerAccess.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import {dispatchPlotProgressUpdate} from '../visualize/ImagePlotCntlr';
12
import Worker from './firefly-thread.worker.js';
23
import {uniqueId} from 'lodash';
34
import {Logger} from '../util/Logger.js';
@@ -33,6 +34,11 @@ function makeWorker(workerKey) {
3334
const worker= new Worker();
3435
worker.onmessage= (ev) => {
3536
const {success,callKey}= ev.data;
37+
if (ev.data.message) {
38+
const {plotId,messageText,requestKey}= ev.data;
39+
dispatchPlotProgressUpdate(plotId,messageText,false,requestKey);
40+
return;
41+
}
3642
if (promiseMap.has(callKey)) {
3743
const pResponse= promiseMap.get(callKey);
3844
if (!success && isWorkerOutOfMemory(ev.data?.error)) {

src/firefly/js/threadWorker/firefly-thread.worker.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import PlotState from '../visualize/PlotState';
12
import {doRawDataWork} from '../visualize/rawData/ManageRawDataThread.js';
23
import {RawDataThreadActions} from './WorkerThreadActions.js';
34

@@ -18,7 +19,17 @@ globalThis.onmessage= (event) => {
1819

1920
function handleRawDataActions(action) {
2021
const {callKey}= action;
21-
doRawDataWork(action)
22+
let sendStatus= () => undefined;
23+
if (action.payload.plotId && action.payload.plotStateSerialized) {
24+
sendStatus= (messageText) => {
25+
const plotState= PlotState.parse(action.payload.plotStateSerialized);
26+
postMessage({message:true,
27+
messageText,
28+
plotId:action.payload.plotId,
29+
requestKey:plotState.getWebPlotRequest().getRequestKey()});
30+
};
31+
}
32+
doRawDataWork({...action,sendStatus})
2233
.then( ({data,transferable}) => postMessage({success:true, ...data, callKey}, transferable) )
2334
.catch( (error) => postMessage({error,callKey, success:false}) );
2435
}

src/firefly/js/visualize/ImageViewerLayout.jsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,6 @@ export const ImageViewerLayout= memo(({ plotView, drawLayersAry, width, height,
5353
const plot= primePlot(plotView);
5454
const hasPlot= Boolean(plot);
5555
const plotShowing= Boolean(viewDim.width && viewDim.height && plot && !plotView.nonRecoverableFail);
56-
const onScreen= !plotShowing || isImageOnScreen(plotView);
57-
const sizeViewable= !plotShowing || isImageSizeViewable(plotView);
58-
const loadingRawData= plotShowing && isImage(plot) && !plot?.tileData && !hasLocalStretchByteData(plot);
5956

6057
useEffect(() => {
6158
if (width && height) {
@@ -131,7 +128,7 @@ export const ImageViewerLayout= memo(({ plotView, drawLayersAry, width, height,
131128
return (
132129
<div className='web-plot-view-scr' style={rootStyle}>
133130
<ImageViewerContents {...{drawLayersAry,plotView,eventCallback:eventCB,cursor,plotShowing}}/>
134-
<MessageArea {...{pv:plotView,plotShowing,onScreen,sizeViewable,loadingRawData}}/>
131+
<MessageArea {...{pv:plotView,plotShowing}}/>
135132
</div>
136133
);
137134

@@ -462,11 +459,15 @@ function sizeChange(previousDim,width,height,viewDim) {
462459
}
463460

464461

465-
function MessageArea({pv,plotShowing,onScreen, sizeViewable, loadingRawData}) {
462+
function MessageArea({pv,plotShowing}) {
463+
const plot= primePlot(pv);
464+
const loadingRawData= plotShowing && isImage(plot) && !plot?.tileData && !hasLocalStretchByteData(plot);
465+
const sizeViewable= !plotShowing || isImageSizeViewable(pv);
466+
const onScreen= !plotShowing || isImageOnScreen(pv);
466467
if (pv.serverCall==='success' && !pv.nonRecoverableFail) {
467468
if (loadingRawData) {
468469
return (
469-
<ImageViewerStatus message={'Loading Image Rendering'} working={true}
470+
<ImageViewerStatus message={`Loading Image Rendering${pv.plottingStatusMsg?': ':''}${pv.plottingStatusMsg}`} working={true}
470471
maskWaitTimeMS= {500} messageWaitTimeMS={1000} useMessageAlpha={plotShowing}/>
471472
);
472473
}

src/firefly/js/visualize/rawData/ManageRawDataThread.js

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {createTileWithGPU} from './RawImageTilesGPU';
1818
const {FETCH_DATA, STRETCH, COLOR, MASK_COLOR, GET_FLUX, REMOVE_RAW_DATA, FETCH_STRETCH_BYTE_DATA, ABORT_FETCH, CLOSE_WHEN_IDLE}= RawDataThreadActions;
1919
const jobRunner= makeJobRunningContext(3);
2020

21-
export async function doRawDataWork({type,payload}) {
21+
export async function doRawDataWork({type,payload,sendStatus}) {
2222
let scheduleClose= false;
2323
if (shouldUseGpuInWorker() && !BrowserInfo.supportsWebGpu() && !getGpuJsImmediate() && payload.rootUrl) {
2424
await getGpuJs(payload.rootUrl); // make sure the GPU code is loaded up front
@@ -28,7 +28,7 @@ export async function doRawDataWork({type,payload}) {
2828

2929
switch (type) {
3030
case ABORT_FETCH: return abortFetch(payload);
31-
case FETCH_STRETCH_BYTE_DATA: return fetchByteDataArray(payload);
31+
case FETCH_STRETCH_BYTE_DATA: return fetchByteDataArray(payload,sendStatus);
3232
case COLOR: return doColorChange(payload);
3333
case MASK_COLOR: return doMaskColorChange(payload);
3434
case REMOVE_RAW_DATA: {
@@ -111,12 +111,12 @@ function convertToBits(ary) {
111111
/**
112112
* @param {StretchWorkerActionPayload} payload
113113
*/
114-
async function fetchByteDataArray(payload) {
114+
async function fetchByteDataArray(payload,sendStatus) {
115115
const {plotImageId,plotStateSerialized, processHeader, dataWidth, dataHeight,
116116
dataCompress=FULL, colorTableId, nanPixelColor} = payload;
117117

118118
try {
119-
const callResults= await callStretchedByteData(payload);
119+
const callResults= await callStretchedByteData(payload,sendStatus);
120120
if (!callResults.success) {
121121
return {data:{success:false, aborted: Boolean(callResults.aborted), type: FETCH_STRETCH_BYTE_DATA, fatal: true, message: callResults.message}};
122122
}
@@ -175,7 +175,7 @@ function getCompressParam(dataCompress, veryLargeData=false) {
175175
* @param {StretchWorkerActionPayload} payload
176176
* @return {Promise<StretchByteDataResults>}
177177
*/
178-
export async function callStretchedByteData(payload ) {
178+
export async function callStretchedByteData(payload,sendStatus ) {
179179

180180
const {plotImageId,plotStateSerialized,plotState, dataWidth,dataHeight,
181181
nanPixelColor,colorTableId, mask=false,maskBits,cmdSrvUrl:url, dataCompress= 'FULL'}= payload;
@@ -213,16 +213,28 @@ export async function callStretchedByteData(payload ) {
213213
let tileNumber=0;
214214

215215
const promiseAry= [];
216+
let totalTiles=0;
217+
let processedTiles=0;
218+
219+
const incUpdateCnt= async () => {
220+
processedTiles++;
221+
if (processedTiles % 4 ===0 && totalTiles) {
222+
sendStatus(`${processedTiles} of ${totalTiles}`);
223+
}
224+
};
225+
216226

217227
for(let i= 0; i<xPanels; i++) {
218228
for (let j = 0; j < yPanels; j++) {
219229
const width = (i < xPanels - 1) ? tileSize : ((realDataWidth - 1) % tileSize + 1);
220230
const height = (j < yPanels - 1) ? tileSize : ((realDataHeight - 1) % tileSize + 1);
221-
promiseAry.push(getATile({tileNumber, colorModel,width,height,payload}));
231+
promiseAry.push(getATile({tileNumber, colorModel,width,height,payload,incUpdateCnt}));
222232
tileNumber++;
223233
}
224234
}
225235

236+
totalTiles= promiseAry.length;
237+
226238
const results= await Promise.allSettled(promiseAry);
227239
const tileResultsAry= results.map( (r) => r.value);
228240
const success= !tileResultsAry.some( (r) => Boolean(r?.error || !r));
@@ -248,7 +260,7 @@ function deleteByteData(url, plotImageId, plotStateSerialized, ct) {
248260
* @param obj.payload
249261
* @return {Promise<{pixelDataStandard: ArrayBuffer, workerBitMapTile: HTMLCanvasElement|OffscreenCanvas|ImageBitmap}>}
250262
*/
251-
async function getATile({tileNumber, colorModel, width, height, payload}) {
263+
async function getATile({tileNumber, colorModel, width, height, payload,incUpdateCnt}) {
252264
const {cmdSrvUrl:url, plotImageId, plotState, plotStateSerialized, mask, maskColor, bias=.5, contrast=1,
253265
dataCompress, veryLargeData}= payload;
254266
const isThreeColor = plotState.isThreeColor();
@@ -277,6 +289,7 @@ async function getATile({tileNumber, colorModel, width, height, payload}) {
277289
const workerBitMapTile= doBitmap
278290
? await createTileWithGPU(inData, colorModel, mask, maskColor, bias, contrast, bandUse)
279291
: undefined;
292+
incUpdateCnt?.();
280293
return {pixelDataStandard:undefined, pixelData3C, workerBitMapTile};
281294
}
282295
else {
@@ -288,6 +301,7 @@ async function getATile({tileNumber, colorModel, width, height, payload}) {
288301
const workerBitMapTile= doBitmap
289302
? await createTileWithGPU(inData, colorModel, mask, maskColor, bias, contrast, undefined)
290303
: undefined;
304+
incUpdateCnt?.();
291305
return {pixelDataStandard, workerBitMapTile};
292306
}
293307
} catch (error) {

src/firefly/js/visualize/rawData/RawDataThreadActionCreators.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export function makeAbortFetchAction(plotImageId, workerKey) {
100100
* @return {WorkerAction}
101101
*/
102102
export function makeRetrieveStretchByteDataAction(plot, plotState, maskOptions, dataCompress, veryLargeData, workerKey) {
103-
const {plotImageId, colorTableId} = plot;
103+
const {plotImageId, colorTableId, plotId} = plot;
104104
const b = plot.plotState.firstBand();
105105
const {processHeader} = plot.rawData.bandData[b.value];
106106
const cleanProcessHeader = {...processHeader, imageCoordSys: processHeader.imageCoordSys.toString()};
@@ -111,6 +111,7 @@ export function makeRetrieveStretchByteDataAction(plot, plotState, maskOptions,
111111
type: RawDataThreadActions.FETCH_STRETCH_BYTE_DATA,
112112
workerKey,
113113
payload: {
114+
plotId,
114115
plotImageId,
115116
dataCompress,
116117
veryLargeData,

src/firefly/js/visualize/reducer/HandlePlotChange.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import {
3030
matchPlotViewByPositionGroup, getPlotViewIdxById, getPlotGroupIdxById, findPlotGroup,
3131
getPlotViewById, findCurrentCenterPoint, getCenterOfProjection,
3232
isRotationMatching, hasWCSProjection, isThreeColor, getHDU, getMatchingRotationAngle, isImageCube,
33-
convertImageIdxToHDU
33+
convertImageIdxToHDU, hasLocalStretchByteData
3434
} from '../PlotViewUtil.js';
3535
import Point, {parseAnyPt, makeImagePt, makeWorldPt, makeDevicePt} from '../Point.js';
3636
import {UserZoomTypes} from '../ZoomUtil.js';
@@ -838,15 +838,22 @@ function requestLocalData(state, action) {
838838
function updatePlotProgress(state,action) {
839839
const {plotId, message:plottingStatusMsg, done, requestKey, callSuccess=true, allowBackwardUpdates= false}= action.payload;
840840
const plotView= getPlotViewById(state,plotId);
841+
const plot= primePlot(plotView);
841842

842843
// validate the update
844+
845+
843846
if (!plotView) return state;
844847
if (requestKey!==plotView.request.getRequestKey()) return state;
845848
if (plotView.plottingStatusMsg===plottingStatusMsg) return state;
846-
if (!done && plotView.serverCall!=='working' && !allowBackwardUpdates) return state;
849+
850+
const tileDataLoading= isImage(plot) && !plot?.tileData && !hasLocalStretchByteData(plot);
851+
if (!done && !tileDataLoading && plotView.serverCall!=='working' && !allowBackwardUpdates) return state;
847852

848853
// do the update
849-
const serverCall= done ? callSuccess ? 'success' : 'fail' : 'working';
854+
855+
const serverCall= (done || tileDataLoading) ? callSuccess ? 'success' : 'fail' : 'working';
856+
850857
return {...state,plotViewAry:clonePvAry(state,plotId, {plottingStatusMsg,serverCall})};
851858
}
852859

src/firefly/js/visualize/reducer/PlotView.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ export function makePlotView(plotId, req, pvOptions= {}) {
132132
plots:[],
133133
visible: pvOptions.visible ?? true,
134134
subHighlight: Boolean(pvOptions.subHighlight ?? false),
135-
request: req && req.makeCopy(),
135+
request: req?.makeCopy(),
136136
plottingStatusMsg:'Plotting...',
137137
serverCall:'success', // one of 'success', 'working', 'fail'
138138
primeIdx: -1,

0 commit comments

Comments
 (0)