feat: request cancel implementation in electron

This commit is contained in:
Anoop M D 2022-10-16 03:06:46 +05:30
parent 118658822d
commit d8cdd2ad8b
5 changed files with 89 additions and 40 deletions

View File

@ -18,9 +18,8 @@ import {
} from 'utils/collections';
import { collectionSchema, itemSchema } from '@usebruno/schema';
import { waitForNextTick } from 'utils/common';
import cancelTokens, { saveCancelToken, deleteCancelToken } from 'utils/network/cancelTokens';
import { getCollectionsFromIdb, saveCollectionToIdb, deleteCollectionInIdb } from 'utils/idb';
import { sendNetworkRequest } from 'utils/network';
import { sendNetworkRequest, cancelNetworkRequest } from 'utils/network';
import {
loadCollections,
@ -208,17 +207,15 @@ export const saveRequest = (itemUid, collectionUid) => (dispatch, getState) => {
};
export const sendRequest = (item, collectionUid) => (dispatch) => {
const axiosRequest = axios.CancelToken.source();
const cancelTokenUid = uuid();
saveCancelToken(cancelTokenUid, axiosRequest);
dispatch(requestSent({
itemUid: item.uid,
collectionUid: collectionUid,
cancelTokenUid: cancelTokenUid
}));
sendNetworkRequest(item, {cancelToken: axiosRequest.token})
sendNetworkRequest(item, {cancelTokenUid: cancelTokenUid})
.then((response) => {
if(response && response.status !== -1) {
return dispatch(responseReceived({
@ -228,18 +225,18 @@ export const sendRequest = (item, collectionUid) => (dispatch) => {
}));
}
})
.then(() => deleteCancelToken(cancelTokenUid))
.catch((err) => console.log(err));
};
export const cancelRequest = (cancelTokenUid, item, collection) => (dispatch) => {
if(cancelTokenUid && cancelTokens[cancelTokenUid]) {
cancelTokens[cancelTokenUid].cancel();
dispatch(requestCancelled({
itemUid: item.uid,
collectionUid: collection.uid
}))
}
cancelNetworkRequest(cancelTokenUid)
.then(() => {
dispatch(requestCancelled({
itemUid: item.uid,
collectionUid: collection.uid
}))
})
.catch((err) => console.log(err));
};
export const newFolder = (folderName, collectionUid, itemUid) => (dispatch, getState) => {

View File

@ -1,22 +1,20 @@
const axios = require('axios');
const FormData = require('form-data');
const { forOwn, extend } = require('lodash');
import { saveCancelToken, deleteCancelToken } from 'utils/network/cancelTokens';
export const sendHttpRequestInBrowser = async (request) => {
export const sendHttpRequestInBrowser = async (request, options) => {
try {
// make axios work in node using form data
// reference: https://github.com/axios/axios/issues/1006#issuecomment-320165427
if(request.headers && request.headers['content-type'] === 'multipart/form-data') {
const form = new FormData();
forOwn(request.data, (value, key) => {
form.append(key, value);
});
extend(request.headers, form.getHeaders());
request.data = form;
if(options && options.cancelTokenUid) {
const cancelToken = axios.CancelToken.source();
request.cancelToken = cancelToken.token;
saveCancelToken(options.cancelTokenUid, cancelToken);
}
const result = await axios(request);
if(options && options.cancelTokenUid) {
deleteCancelToken(options.cancelTokenUid);
}
return {
status: result.status,
headers: result.headers,

View File

@ -3,8 +3,10 @@ import filter from 'lodash/filter';
import qs from 'qs';
import { rawRequest, gql } from 'graphql';
import { sendHttpRequestInBrowser } from './browser';
import { isElectron } from 'utils/common/platform';
import cancelTokens, { deleteCancelToken } from 'utils/network/cancelTokens';
const sendNetworkRequest = async (item, options) => {
export const sendNetworkRequest = async (item, options) => {
return new Promise((resolve, reject) => {
if(item.type === 'http-request') {
const timeStart = Date.now();
@ -42,10 +44,6 @@ const sendHttpRequest = async (request, options) => {
headers: headers
};
if(options && options.cancelToken) {
axiosRequest.cancelToken = options.cancelToken;
}
if(request.body.mode === 'json') {
axiosRequest.headers['content-type'] = 'application/json';
try {
@ -84,15 +82,16 @@ const sendHttpRequest = async (request, options) => {
console.log('>>> Sending Request');
console.log(axiosRequest);
// Todo: Choose based on platform (web/desktop)
sendHttpRequestInBrowser(axiosRequest)
if(isElectron()) {
ipcRenderer
.invoke('send-http-request', axiosRequest, options)
.then(resolve)
.catch(reject);
// ipcRenderer
// .invoke('send-http', axiosRequest)
// .then(resolve)
// .catch(reject);
} else {
sendHttpRequestInBrowser(axiosRequest, options)
.then(resolve)
.catch(reject);
}
});
};
@ -109,6 +108,23 @@ const sendGraphqlRequest = async (request,) => {
}
};
export {
sendNetworkRequest
export const cancelNetworkRequest = async (cancelTokenUid) => {
if(isElectron()) {
return new Promise((resolve, reject) => {
ipcRenderer
.invoke('cancel-http-request', cancelTokenUid)
.then(resolve)
.catch(reject);
});
}
return new Promise((resolve, reject) => {
if(cancelTokenUid && cancelTokens[cancelTokenUid]) {
cancelTokens[cancelTokenUid].cancel();
deleteCancelToken(cancelTokenUid);
resolve();
} else {
reject(new Error("cancel token not found"));
}
});
};

View File

@ -2,10 +2,11 @@ const axios = require('axios');
const FormData = require('form-data');
const { ipcMain } = require('electron');
const { forOwn, extend } = require('lodash');
const { cancelTokens, saveCancelToken, deleteCancelToken } = require('../utils/cancel-token');
const registerNetworkIpc = () => {
// handler for sending http request
ipcMain.handle('send-http-request', async (event, request) => {
ipcMain.handle('send-http-request', async (event, request, options) => {
try {
// make axios work in node using form data
// reference: https://github.com/axios/axios/issues/1006#issuecomment-320165427
@ -18,8 +19,18 @@ const registerNetworkIpc = () => {
request.data = form;
}
if(options && options.cancelTokenUid) {
const cancelToken = axios.CancelToken.source();
request.cancelToken = cancelToken.token;
saveCancelToken(options.cancelTokenUid, cancelToken);
}
const result = await axios(request);
if(options && options.cancelTokenUid) {
deleteCancelToken(options.cancelTokenUid);
}
return {
status: result.status,
headers: result.headers,
@ -41,6 +52,18 @@ const registerNetworkIpc = () => {
};
}
});
ipcMain.handle('cancel-http-request', async (event, cancelTokenUid) => {
return new Promise((resolve, reject) => {
if(cancelTokenUid && cancelTokens[cancelTokenUid]) {
cancelTokens[cancelTokenUid].cancel();
deleteCancelToken(cancelTokenUid);
resolve();
} else {
reject(new Error("cancel token not found"));
}
});
});
};
module.exports = registerNetworkIpc;

View File

@ -0,0 +1,15 @@
const cancelTokens = {};
const saveCancelToken = (uid, axiosRequest) => {
cancelTokens[uid] = axiosRequest;
}
const deleteCancelToken = (uid) => {
delete cancelTokens[uid];
}
module.exports = {
cancelTokens,
saveCancelToken,
deleteCancelToken
};