github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/webapp/javascript/redux/reducers/continuous/timelines.thunks.ts (about) 1 import { RenderOutput, renderSingle } from '@webapp/services/render'; 2 import { RequestAbortedError } from '@webapp/services/base'; 3 import { addNotification } from '../notifications'; 4 import { createAsyncThunk } from '../../async-thunk'; 5 import { ContinuousState } from './state'; 6 7 let sideTimelinesAbortController: AbortController | undefined; 8 9 export const fetchSideTimelines = createAsyncThunk< 10 { left: RenderOutput; right: RenderOutput }, 11 null, 12 { state: { continuous: ContinuousState } } 13 >('continuous/fetchSideTimelines', async (_, thunkAPI) => { 14 if (sideTimelinesAbortController) { 15 sideTimelinesAbortController.abort(); 16 } 17 18 sideTimelinesAbortController = new AbortController(); 19 thunkAPI.signal = sideTimelinesAbortController.signal; 20 21 const state = thunkAPI.getState(); 22 23 const res = await Promise.all([ 24 renderSingle( 25 { 26 query: state.continuous.leftQuery || '', 27 from: state.continuous.from, 28 until: state.continuous.until, 29 maxNodes: state.continuous.maxNodes, 30 refreshToken: state.continuous.refreshToken, 31 }, 32 sideTimelinesAbortController 33 ), 34 renderSingle( 35 { 36 query: state.continuous.rightQuery || '', 37 from: state.continuous.from, 38 until: state.continuous.until, 39 maxNodes: state.continuous.maxNodes, 40 refreshToken: state.continuous.refreshToken, 41 }, 42 sideTimelinesAbortController 43 ), 44 ]); 45 46 if ( 47 (res?.[0]?.isErr && res?.[0]?.error instanceof RequestAbortedError) || 48 (res?.[1]?.isErr && res?.[1]?.error instanceof RequestAbortedError) || 49 (!res && thunkAPI.signal.aborted) 50 ) { 51 return Promise.reject(); 52 } 53 54 if (res?.[0].isOk && res?.[1].isOk) { 55 return Promise.resolve({ 56 left: res[0].value, 57 right: res[1].value, 58 }); 59 } 60 61 thunkAPI.dispatch( 62 addNotification({ 63 type: 'danger', 64 title: `Failed to load the timelines`, 65 message: '', 66 additionalInfo: [ 67 res?.[0].error.message, 68 res?.[1].error.message, 69 ] as string[], 70 }) 71 ); 72 73 return Promise.reject(res && res.filter((a) => a?.isErr).map((a) => a.error)); 74 });