mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2024-11-22 08:46:39 -06:00
Use fetch instead of axios to close connections in SQLEditor, ERD, Schema Diff and Debugger to ensure it completes. When closing a browser tab, axios does not guarantee AJAX request completion. #5894
This commit is contained in:
parent
64aa739224
commit
b923f5fcfa
@ -47,3 +47,14 @@ export function parseApiError(error) {
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function callFetch(url, options, headers={}) {
|
||||||
|
return fetch(url, {
|
||||||
|
...options,
|
||||||
|
headers: {
|
||||||
|
'Content-type': 'application/json',
|
||||||
|
[pgAdmin.csrf_token_header]: pgAdmin.csrf_token,
|
||||||
|
...headers,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -427,17 +427,6 @@ export default class DebuggerModule {
|
|||||||
setDebuggerTitle(panel, browser_preferences, label, newTreeInfo.schema.label, db_label, null, self.pgBrowser);
|
setDebuggerTitle(panel, browser_preferences, label, newTreeInfo.schema.label, db_label, null, self.pgBrowser);
|
||||||
|
|
||||||
panel.focus();
|
panel.focus();
|
||||||
// Register Panel Closed event
|
|
||||||
panel.on(self.wcDocker.EVENT.CLOSED, function () {
|
|
||||||
let closeUrl = url_for('debugger.close', {
|
|
||||||
'trans_id': trans_id,
|
|
||||||
});
|
|
||||||
self.api({
|
|
||||||
url: closeUrl,
|
|
||||||
method: 'DELETE',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
panel.on(self.wcDocker.EVENT.RENAME, function (panel_data) {
|
panel.on(self.wcDocker.EVENT.RENAME, function (panel_data) {
|
||||||
self.panel_rename_event(panel_data, panel, treeInfo);
|
self.panel_rename_event(panel_data, panel, treeInfo);
|
||||||
});
|
});
|
||||||
@ -607,17 +596,6 @@ export default class DebuggerModule {
|
|||||||
|
|
||||||
panel.focus();
|
panel.focus();
|
||||||
|
|
||||||
// Panel Closed event
|
|
||||||
panel.on(self.wcDocker.EVENT.CLOSED, function () {
|
|
||||||
let closeUrl = url_for('debugger.close', {
|
|
||||||
'trans_id': res.data.data.debuggerTransId,
|
|
||||||
});
|
|
||||||
self.api({
|
|
||||||
url: closeUrl,
|
|
||||||
method: 'DELETE',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Panel Rename event
|
// Panel Rename event
|
||||||
panel.on(self.wcDocker.EVENT.RENAME, function (panel_data) {
|
panel.on(self.wcDocker.EVENT.RENAME, function (panel_data) {
|
||||||
self.panel_rename_event(panel_data, panel, treeInfo);
|
self.panel_rename_event(panel_data, panel, treeInfo);
|
||||||
|
@ -741,16 +741,6 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug,
|
|||||||
setDebuggerTitle(panel, browser_pref, label, treeInfo.schema.label, treeInfo.database.label, null, pgAdmin.Browser);
|
setDebuggerTitle(panel, browser_pref, label, treeInfo.schema.label, treeInfo.database.label, null, pgAdmin.Browser);
|
||||||
panel.focus();
|
panel.focus();
|
||||||
|
|
||||||
// Panel Closed event
|
|
||||||
panel.on(wcDocker.EVENT.CLOSED, function () {
|
|
||||||
let closeUrl = url_for('debugger.close', {
|
|
||||||
'trans_id': res_post.data.data.debuggerTransId,
|
|
||||||
});
|
|
||||||
api({
|
|
||||||
url: closeUrl,
|
|
||||||
method: 'DELETE',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
/* TO-DO check how to add this is new lib for wc-docker */
|
/* TO-DO check how to add this is new lib for wc-docker */
|
||||||
commonUtils.registerDetachEvent(panel);
|
commonUtils.registerDetachEvent(panel);
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ import Loader from 'sources/components/Loader';
|
|||||||
|
|
||||||
import Layout, { LayoutHelper } from '../../../../../static/js/helpers/Layout';
|
import Layout, { LayoutHelper } from '../../../../../static/js/helpers/Layout';
|
||||||
import EventBus from '../../../../../static/js/helpers/EventBus';
|
import EventBus from '../../../../../static/js/helpers/EventBus';
|
||||||
import getApiInstance from '../../../../../static/js/api_instance';
|
import getApiInstance, { callFetch } from '../../../../../static/js/api_instance';
|
||||||
import Notify from '../../../../../static/js/helpers/Notifier';
|
import Notify from '../../../../../static/js/helpers/Notifier';
|
||||||
|
|
||||||
import { evalFunc } from '../../../../../static/js/utils';
|
import { evalFunc } from '../../../../../static/js/utils';
|
||||||
@ -380,6 +380,27 @@ export default function DebuggerComponent({ pgAdmin, selectedNodeInfo, panel, ev
|
|||||||
.catch(raiseJSONError);
|
.catch(raiseJSONError);
|
||||||
messages(params.transId);
|
messages(params.transId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const closeConn = ()=>{
|
||||||
|
/* Using fetch with keepalive as the browser may
|
||||||
|
cancel the axios request on tab close. keepalive will
|
||||||
|
make sure the request is completed */
|
||||||
|
callFetch(
|
||||||
|
url_for('debugger.close', {
|
||||||
|
'trans_id': params.transId,
|
||||||
|
}), {
|
||||||
|
keepalive: true,
|
||||||
|
method: 'DELETE',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(()=>{/* Success */})
|
||||||
|
.catch((err)=>console.error(err));
|
||||||
|
};
|
||||||
|
window.addEventListener('unload', closeConn);
|
||||||
|
|
||||||
|
return ()=>{
|
||||||
|
window.removeEventListener('unload', closeConn);
|
||||||
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const setUnsetBreakpoint = (res, breakpoint_list) => {
|
const setUnsetBreakpoint = (res, breakpoint_list) => {
|
||||||
|
@ -8,26 +8,6 @@ try {
|
|||||||
function(pgDirectDebug, pgAdmin) {
|
function(pgDirectDebug, pgAdmin) {
|
||||||
var pgDebug = window.pgAdmin.Tools.Debugger;
|
var pgDebug = window.pgAdmin.Tools.Debugger;
|
||||||
pgDebug.load(document.getElementById('debugger-main-container'), {{ uniqueId }}, {{ debug_type }}, '{{ function_name_with_arguments }}', '{{layout|safe}}');
|
pgDebug.load(document.getElementById('debugger-main-container'), {{ uniqueId }}, {{ debug_type }}, '{{ function_name_with_arguments }}', '{{layout|safe}}');
|
||||||
|
|
||||||
// Register unload event on window close.
|
|
||||||
/* If opened in new tab, close the connection only on tab/window close and
|
|
||||||
* not on refresh attempt because the user may cancel the reload
|
|
||||||
*/
|
|
||||||
if(window.opener) {
|
|
||||||
$(window).on('unload', function(ev) {
|
|
||||||
$.ajax({
|
|
||||||
method: 'DELETE',
|
|
||||||
url: "{{ url_for('debugger.index') }}close/{{ uniqueId }}"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$(window).on('beforeunload', function(ev) {
|
|
||||||
$.ajax({
|
|
||||||
method: 'DELETE',
|
|
||||||
url: "{{ url_for('debugger.index') }}close/{{ uniqueId }}"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
function() {
|
function() {
|
||||||
console.log(arguments);
|
console.log(arguments);
|
||||||
|
@ -31,7 +31,7 @@ import { MainToolBar } from './MainToolBar';
|
|||||||
import { Box, withStyles } from '@material-ui/core';
|
import { Box, withStyles } from '@material-ui/core';
|
||||||
import EventBus from '../../../../../../static/js/helpers/EventBus';
|
import EventBus from '../../../../../../static/js/helpers/EventBus';
|
||||||
import { ERD_EVENTS } from '../ERDConstants';
|
import { ERD_EVENTS } from '../ERDConstants';
|
||||||
import getApiInstance, { parseApiError } from '../../../../../../static/js/api_instance';
|
import getApiInstance, { callFetch, parseApiError } from '../../../../../../static/js/api_instance';
|
||||||
import { openSocket, socketApiGet } from '../../../../../../static/js/socket_instance';
|
import { openSocket, socketApiGet } from '../../../../../../static/js/socket_instance';
|
||||||
|
|
||||||
/* Custom react-diagram action for keyboard events */
|
/* Custom react-diagram action for keyboard events */
|
||||||
@ -333,12 +333,22 @@ class ERDTool extends React.Component {
|
|||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('unload', ()=>{
|
window.addEventListener('unload', ()=>{
|
||||||
this.apiObj.delete(url_for('erd.close', {
|
/* Using fetch with keepalive as the browser may
|
||||||
trans_id: this.props.params.trans_id,
|
cancel the axios request on tab close. keepalive will
|
||||||
sgid: this.props.params.sgid,
|
make sure the request is completed */
|
||||||
sid: this.props.params.sid,
|
callFetch(
|
||||||
did: this.props.params.did
|
url_for('erd.close', {
|
||||||
}));
|
trans_id: this.props.params.trans_id,
|
||||||
|
sgid: this.props.params.sgid,
|
||||||
|
sid: this.props.params.sid,
|
||||||
|
did: this.props.params.did
|
||||||
|
}), {
|
||||||
|
keepalive: true,
|
||||||
|
method: 'DELETE',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(()=>{/* Success */})
|
||||||
|
.catch((err)=>console.error(err));
|
||||||
});
|
});
|
||||||
|
|
||||||
let done = await this.initConnection();
|
let done = await this.initConnection();
|
||||||
|
@ -19,7 +19,7 @@ import { Box, makeStyles } from '@material-ui/core';
|
|||||||
import { Results } from './Results';
|
import { Results } from './Results';
|
||||||
import { SchemaDiffCompare } from './SchemaDiffCompare';
|
import { SchemaDiffCompare } from './SchemaDiffCompare';
|
||||||
import EventBus from '../../../../../static/js/helpers/EventBus';
|
import EventBus from '../../../../../static/js/helpers/EventBus';
|
||||||
import getApiInstance from '../../../../../static/js/api_instance';
|
import getApiInstance, { callFetch } from '../../../../../static/js/api_instance';
|
||||||
import { useModal } from '../../../../../static/js/helpers/ModalProvider';
|
import { useModal } from '../../../../../static/js/helpers/ModalProvider';
|
||||||
|
|
||||||
export const SchemaDiffEventsContext = createContext();
|
export const SchemaDiffEventsContext = createContext();
|
||||||
@ -78,9 +78,19 @@ export default function SchemaDiffComponent({params}) {
|
|||||||
|
|
||||||
function registerUnload() {
|
function registerUnload() {
|
||||||
window.addEventListener('unload', ()=>{
|
window.addEventListener('unload', ()=>{
|
||||||
api.delete(url_for('schema_diff.close', {
|
/* Using fetch with keepalive as the browser may
|
||||||
trans_id: params.transId
|
cancel the axios request on tab close. keepalive will
|
||||||
}));
|
make sure the request is completed */
|
||||||
|
callFetch(
|
||||||
|
url_for('schema_diff.close', {
|
||||||
|
trans_id: params.transId
|
||||||
|
}), {
|
||||||
|
keepalive: true,
|
||||||
|
method: 'DELETE',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(()=>{/* Success */})
|
||||||
|
.catch((err)=>console.error(err));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ import { ResultSet } from './sections/ResultSet';
|
|||||||
import { StatusBar } from './sections/StatusBar';
|
import { StatusBar } from './sections/StatusBar';
|
||||||
import { MainToolBar } from './sections/MainToolBar';
|
import { MainToolBar } from './sections/MainToolBar';
|
||||||
import { Messages } from './sections/Messages';
|
import { Messages } from './sections/Messages';
|
||||||
import getApiInstance, {parseApiError} from '../../../../../static/js/api_instance';
|
import getApiInstance, {callFetch, parseApiError} from '../../../../../static/js/api_instance';
|
||||||
import url_for from 'sources/url_for';
|
import url_for from 'sources/url_for';
|
||||||
import { PANELS, QUERY_TOOL_EVENTS, CONNECTION_STATUS } from './QueryToolConstants';
|
import { PANELS, QUERY_TOOL_EVENTS, CONNECTION_STATUS } from './QueryToolConstants';
|
||||||
import { useInterval } from '../../../../../static/js/custom_hooks';
|
import { useInterval } from '../../../../../static/js/custom_hooks';
|
||||||
@ -359,11 +359,19 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
|
|||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
const closeConn = ()=>{
|
const closeConn = ()=>{
|
||||||
api.delete(
|
/* Using fetch with keepalive as the browser may
|
||||||
|
cancel the axios request on tab close. keepalive will
|
||||||
|
make sure the request is completed */
|
||||||
|
callFetch(
|
||||||
url_for('sqleditor.close', {
|
url_for('sqleditor.close', {
|
||||||
'trans_id': qtState.params.trans_id,
|
'trans_id': qtState.params.trans_id,
|
||||||
})
|
}), {
|
||||||
);
|
keepalive: true,
|
||||||
|
method: 'DELETE',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(()=>{/* Success */})
|
||||||
|
.catch((err)=>console.error(err));
|
||||||
};
|
};
|
||||||
window.addEventListener('unload', closeConn);
|
window.addEventListener('unload', closeConn);
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import ERDCore from 'pgadmin.tools.erd/erd_tool/ERDCore';
|
|||||||
import * as createEngineLib from '@projectstorm/react-diagrams';
|
import * as createEngineLib from '@projectstorm/react-diagrams';
|
||||||
import TEST_TABLES_DATA from './test_tables';
|
import TEST_TABLES_DATA from './test_tables';
|
||||||
import { FakeLink, FakeNode } from './fake_item';
|
import { FakeLink, FakeNode } from './fake_item';
|
||||||
import { PortModelAlignment, PathFindingLinkFactory } from '@projectstorm/react-diagrams';
|
import { PortModelAlignment } from '@projectstorm/react-diagrams';
|
||||||
|
|
||||||
describe('ERDCore', ()=>{
|
describe('ERDCore', ()=>{
|
||||||
let eleFactory = jasmine.createSpyObj('nodeFactories', {
|
let eleFactory = jasmine.createSpyObj('nodeFactories', {
|
||||||
@ -45,7 +45,6 @@ describe('ERDCore', ()=>{
|
|||||||
|
|
||||||
beforeAll(()=>{
|
beforeAll(()=>{
|
||||||
spyOn(createEngineLib, 'default').and.returnValue(erdEngine);
|
spyOn(createEngineLib, 'default').and.returnValue(erdEngine);
|
||||||
spyOn(PathFindingLinkFactory.prototype, 'calculateRoutingMatrix').and.callFake(()=>{/* intentionally empty */});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('initialization', ()=>{
|
it('initialization', ()=>{
|
||||||
|
Loading…
Reference in New Issue
Block a user