mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-26 04:05:59 +00:00
close query sessions after timeout #468
This commit is contained in:
@@ -10,6 +10,7 @@ const processArgs = require('../utility/processArgs');
|
|||||||
const { appdir } = require('../utility/directories');
|
const { appdir } = require('../utility/directories');
|
||||||
const { getLogger } = require('dbgate-tools');
|
const { getLogger } = require('dbgate-tools');
|
||||||
const pipeForkLogs = require('../utility/pipeForkLogs');
|
const pipeForkLogs = require('../utility/pipeForkLogs');
|
||||||
|
const config = require('./config');
|
||||||
|
|
||||||
const logger = getLogger('sessions');
|
const logger = getLogger('sessions');
|
||||||
|
|
||||||
@@ -120,7 +121,12 @@ module.exports = {
|
|||||||
socket.emit(`session-closed-${sesid}`);
|
socket.emit(`session-closed-${sesid}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
subprocess.send({ msgtype: 'connect', ...connection, database });
|
subprocess.send({
|
||||||
|
msgtype: 'connect',
|
||||||
|
...connection,
|
||||||
|
database,
|
||||||
|
globalSettings: await config.getSettings(),
|
||||||
|
});
|
||||||
return _.pick(newOpened, ['conid', 'database', 'sesid']);
|
return _.pick(newOpened, ['conid', 'database', 'sesid']);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const requireEngineDriver = require('../utility/requireEngineDriver');
|
|||||||
const { decryptConnection } = require('../utility/crypting');
|
const { decryptConnection } = require('../utility/crypting');
|
||||||
const connectUtility = require('../utility/connectUtility');
|
const connectUtility = require('../utility/connectUtility');
|
||||||
const { handleProcessCommunication } = require('../utility/processComm');
|
const { handleProcessCommunication } = require('../utility/processComm');
|
||||||
const { getLogger } = require('dbgate-tools');
|
const { getLogger, extractIntSettingsValue, extractBoolSettingsValue } = require('dbgate-tools');
|
||||||
|
|
||||||
const logger = getLogger('sessionProcess');
|
const logger = getLogger('sessionProcess');
|
||||||
|
|
||||||
@@ -19,6 +19,7 @@ let storedConnection;
|
|||||||
let afterConnectCallbacks = [];
|
let afterConnectCallbacks = [];
|
||||||
// let currentHandlers = [];
|
// let currentHandlers = [];
|
||||||
let lastPing = null;
|
let lastPing = null;
|
||||||
|
let lastActivity = null;
|
||||||
let currentProfiler = null;
|
let currentProfiler = null;
|
||||||
|
|
||||||
class TableWriter {
|
class TableWriter {
|
||||||
@@ -215,6 +216,8 @@ function waitConnected() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleStartProfiler({ jslid }) {
|
async function handleStartProfiler({ jslid }) {
|
||||||
|
lastActivity = new Date().getTime();
|
||||||
|
|
||||||
await waitConnected();
|
await waitConnected();
|
||||||
const driver = requireEngineDriver(storedConnection);
|
const driver = requireEngineDriver(storedConnection);
|
||||||
|
|
||||||
@@ -233,6 +236,8 @@ async function handleStartProfiler({ jslid }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleStopProfiler({ jslid }) {
|
async function handleStopProfiler({ jslid }) {
|
||||||
|
lastActivity = new Date().getTime();
|
||||||
|
|
||||||
const driver = requireEngineDriver(storedConnection);
|
const driver = requireEngineDriver(storedConnection);
|
||||||
currentProfiler.writer.close();
|
currentProfiler.writer.close();
|
||||||
driver.stopProfiler(systemConnection, currentProfiler);
|
driver.stopProfiler(systemConnection, currentProfiler);
|
||||||
@@ -240,6 +245,8 @@ async function handleStopProfiler({ jslid }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleExecuteQuery({ sql }) {
|
async function handleExecuteQuery({ sql }) {
|
||||||
|
lastActivity = new Date().getTime();
|
||||||
|
|
||||||
await waitConnected();
|
await waitConnected();
|
||||||
const driver = requireEngineDriver(storedConnection);
|
const driver = requireEngineDriver(storedConnection);
|
||||||
|
|
||||||
@@ -273,6 +280,8 @@ async function handleExecuteQuery({ sql }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleExecuteReader({ jslid, sql, fileName }) {
|
async function handleExecuteReader({ jslid, sql, fileName }) {
|
||||||
|
lastActivity = new Date().getTime();
|
||||||
|
|
||||||
await waitConnected();
|
await waitConnected();
|
||||||
|
|
||||||
const driver = requireEngineDriver(storedConnection);
|
const driver = requireEngineDriver(storedConnection);
|
||||||
@@ -331,6 +340,19 @@ function start() {
|
|||||||
logger.info('Session not alive, exiting');
|
logger.info('Session not alive, exiting');
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const useSessionTimeout =
|
||||||
|
storedConnection && storedConnection.globalSettings
|
||||||
|
? extractBoolSettingsValue(storedConnection.globalSettings, 'session.autoClose', true)
|
||||||
|
: false;
|
||||||
|
const sessionTimeout =
|
||||||
|
storedConnection && storedConnection.globalSettings
|
||||||
|
? extractIntSettingsValue(storedConnection.globalSettings, 'session.autoCloseTimeout', 15, 1, 120)
|
||||||
|
: 15;
|
||||||
|
if (useSessionTimeout && time - lastActivity > sessionTimeout * 60 * 1000 && !currentProfiler) {
|
||||||
|
logger.info('Session not active, exiting');
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
}, 10 * 1000);
|
}, 10 * 1000);
|
||||||
|
|
||||||
process.on('message', async message => {
|
process.on('message', async message => {
|
||||||
|
|||||||
@@ -69,9 +69,10 @@ ORDER BY
|
|||||||
isInline
|
isInline
|
||||||
tabs={[
|
tabs={[
|
||||||
{ label: 'General', slot: 1 },
|
{ label: 'General', slot: 1 },
|
||||||
{ label: 'Themes', slot: 2 },
|
{ label: 'Connection', slot: 2 },
|
||||||
{ label: 'Default Actions', slot: 3 },
|
{ label: 'Themes', slot: 3 },
|
||||||
{ label: 'Confirmations', slot: 4 },
|
{ label: 'Default Actions', slot: 4 },
|
||||||
|
{ label: 'Confirmations', slot: 5 },
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<svelte:fragment slot="1">
|
<svelte:fragment slot="1">
|
||||||
@@ -108,6 +109,19 @@ ORDER BY
|
|||||||
defaultValue="10"
|
defaultValue="10"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<div class="heading">SQL editor</div>
|
||||||
|
<FormSelectField
|
||||||
|
label="SQL commands case"
|
||||||
|
name="sqlEditor.sqlCommandsCase"
|
||||||
|
isNative
|
||||||
|
defaultValue="upperCase"
|
||||||
|
options={[
|
||||||
|
{ value: 'upperCase', label: 'UPPER CASE' },
|
||||||
|
{ value: 'lowerCase', label: 'lower case' },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</svelte:fragment>
|
||||||
|
<svelte:fragment slot="2">
|
||||||
<div class="heading">Connection</div>
|
<div class="heading">Connection</div>
|
||||||
|
|
||||||
<FormFieldTemplateLarge
|
<FormFieldTemplateLarge
|
||||||
@@ -134,19 +148,21 @@ ORDER BY
|
|||||||
disabled={values['connection.autoRefresh'] === false}
|
disabled={values['connection.autoRefresh'] === false}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="heading">SQL editor</div>
|
<div class="heading">Query sessions</div>
|
||||||
<FormSelectField
|
<FormCheckboxField
|
||||||
label="SQL commands case"
|
name="session.autoClose"
|
||||||
name="sqlEditor.sqlCommandsCase"
|
label="Automatic close query sessions after period without any activity"
|
||||||
isNative
|
defaultValue={true}
|
||||||
defaultValue="upperCase"
|
/>
|
||||||
options={[
|
<FormTextField
|
||||||
{ value: 'upperCase', label: 'UPPER CASE' },
|
name="session.autoCloseTimeout"
|
||||||
{ value: 'lowerCase', label: 'lower case' },
|
label="Interval, after which query session without activity is closed (in minutes)"
|
||||||
]}
|
defaultValue="15"
|
||||||
|
disabled={values['session.autoClose'] === false}
|
||||||
/>
|
/>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
<svelte:fragment slot="2">
|
|
||||||
|
<svelte:fragment slot="3">
|
||||||
<div class="heading">Application theme</div>
|
<div class="heading">Application theme</div>
|
||||||
<div class="themes">
|
<div class="themes">
|
||||||
{#each $extensions.themes as theme}
|
{#each $extensions.themes as theme}
|
||||||
@@ -207,7 +223,7 @@ ORDER BY
|
|||||||
<SqlEditor value={sqlPreview} readOnly />
|
<SqlEditor value={sqlPreview} readOnly />
|
||||||
</div>
|
</div>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
<svelte:fragment slot="3">
|
<svelte:fragment slot="4">
|
||||||
<div class="heading">Default actions</div>
|
<div class="heading">Default actions</div>
|
||||||
<FormSelectField
|
<FormSelectField
|
||||||
label="Connection click"
|
label="Connection click"
|
||||||
@@ -271,7 +287,7 @@ ORDER BY
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
<svelte:fragment slot="4">
|
<svelte:fragment slot="5">
|
||||||
<div class="heading">Confirmations</div>
|
<div class="heading">Confirmations</div>
|
||||||
|
|
||||||
<FormCheckboxField name="skipConfirm.tableDataSave" label="Skip confirmation when saving table data (SQL)" />
|
<FormCheckboxField name="skipConfirm.tableDataSave" label="Skip confirmation when saving table data (SQL)" />
|
||||||
|
|||||||
Reference in New Issue
Block a user