mirror of
https://github.com/getredash/redash.git
synced 2025-12-19 17:37:19 -05:00
Change query processing wait time to make response quick (#7320)
* Change query processing wait time to make more response quick * Fix styling errors reportered by restyled
This commit is contained in:
@@ -9,7 +9,7 @@ const logger = debug("redash:services:QueryResult");
|
|||||||
const filterTypes = ["filter", "multi-filter", "multiFilter"];
|
const filterTypes = ["filter", "multi-filter", "multiFilter"];
|
||||||
|
|
||||||
function defer() {
|
function defer() {
|
||||||
const result = { onStatusChange: status => {} };
|
const result = { onStatusChange: (status) => {} };
|
||||||
result.promise = new Promise((resolve, reject) => {
|
result.promise = new Promise((resolve, reject) => {
|
||||||
result.resolve = resolve;
|
result.resolve = resolve;
|
||||||
result.reject = reject;
|
result.reject = reject;
|
||||||
@@ -40,13 +40,13 @@ function getColumnNameWithoutType(column) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getColumnFriendlyName(column) {
|
function getColumnFriendlyName(column) {
|
||||||
return getColumnNameWithoutType(column).replace(/(?:^|\s)\S/g, a => a.toUpperCase());
|
return getColumnNameWithoutType(column).replace(/(?:^|\s)\S/g, (a) => a.toUpperCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
const createOrSaveUrl = data => (data.id ? `api/query_results/${data.id}` : "api/query_results");
|
const createOrSaveUrl = (data) => (data.id ? `api/query_results/${data.id}` : "api/query_results");
|
||||||
const QueryResultResource = {
|
const QueryResultResource = {
|
||||||
get: ({ id }) => axios.get(`api/query_results/${id}`),
|
get: ({ id }) => axios.get(`api/query_results/${id}`),
|
||||||
post: data => axios.post(createOrSaveUrl(data), data),
|
post: (data) => axios.post(createOrSaveUrl(data), data),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ExecutionStatus = {
|
export const ExecutionStatus = {
|
||||||
@@ -97,11 +97,11 @@ function handleErrorResponse(queryResult, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function sleep(ms) {
|
function sleep(ms) {
|
||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchDataFromJob(jobId, interval = 1000) {
|
export function fetchDataFromJob(jobId, interval = 1000) {
|
||||||
return axios.get(`api/jobs/${jobId}`).then(data => {
|
return axios.get(`api/jobs/${jobId}`).then((data) => {
|
||||||
const status = statuses[data.job.status];
|
const status = statuses[data.job.status];
|
||||||
if (status === ExecutionStatus.WAITING || status === ExecutionStatus.PROCESSING) {
|
if (status === ExecutionStatus.WAITING || status === ExecutionStatus.PROCESSING) {
|
||||||
return sleep(interval).then(() => fetchDataFromJob(data.job.id));
|
return sleep(interval).then(() => fetchDataFromJob(data.job.id));
|
||||||
@@ -146,7 +146,7 @@ class QueryResult {
|
|||||||
// TODO: we should stop manipulating incoming data, and switch to relaying
|
// TODO: we should stop manipulating incoming data, and switch to relaying
|
||||||
// on the column type set by the backend. This logic is prone to errors,
|
// on the column type set by the backend. This logic is prone to errors,
|
||||||
// and better be removed. Kept for now, for backward compatability.
|
// and better be removed. Kept for now, for backward compatability.
|
||||||
each(this.query_result.data.rows, row => {
|
each(this.query_result.data.rows, (row) => {
|
||||||
forOwn(row, (v, k) => {
|
forOwn(row, (v, k) => {
|
||||||
let newType = null;
|
let newType = null;
|
||||||
if (isNumber(v)) {
|
if (isNumber(v)) {
|
||||||
@@ -173,7 +173,7 @@ class QueryResult {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
each(this.query_result.data.columns, column => {
|
each(this.query_result.data.columns, (column) => {
|
||||||
column.name = "" + column.name;
|
column.name = "" + column.name;
|
||||||
if (columnTypes[column.name]) {
|
if (columnTypes[column.name]) {
|
||||||
if (column.type == null || column.type === "string") {
|
if (column.type == null || column.type === "string") {
|
||||||
@@ -265,14 +265,14 @@ class QueryResult {
|
|||||||
|
|
||||||
getColumnNames() {
|
getColumnNames() {
|
||||||
if (this.columnNames === undefined && this.query_result.data) {
|
if (this.columnNames === undefined && this.query_result.data) {
|
||||||
this.columnNames = this.query_result.data.columns.map(v => v.name);
|
this.columnNames = this.query_result.data.columns.map((v) => v.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.columnNames;
|
return this.columnNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
getColumnFriendlyNames() {
|
getColumnFriendlyNames() {
|
||||||
return this.getColumnNames().map(col => getColumnFriendlyName(col));
|
return this.getColumnNames().map((col) => getColumnFriendlyName(col));
|
||||||
}
|
}
|
||||||
|
|
||||||
getTruncated() {
|
getTruncated() {
|
||||||
@@ -286,7 +286,7 @@ class QueryResult {
|
|||||||
|
|
||||||
const filters = [];
|
const filters = [];
|
||||||
|
|
||||||
this.getColumns().forEach(col => {
|
this.getColumns().forEach((col) => {
|
||||||
const name = col.name;
|
const name = col.name;
|
||||||
const type = name.split("::")[1] || name.split("__")[1];
|
const type = name.split("::")[1] || name.split("__")[1];
|
||||||
if (includes(filterTypes, type)) {
|
if (includes(filterTypes, type)) {
|
||||||
@@ -302,8 +302,8 @@ class QueryResult {
|
|||||||
}
|
}
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
this.getRawData().forEach(row => {
|
this.getRawData().forEach((row) => {
|
||||||
filters.forEach(filter => {
|
filters.forEach((filter) => {
|
||||||
filter.values.push(row[filter.name]);
|
filter.values.push(row[filter.name]);
|
||||||
if (filter.values.length === 1) {
|
if (filter.values.length === 1) {
|
||||||
if (filter.multiple) {
|
if (filter.multiple) {
|
||||||
@@ -315,8 +315,8 @@ class QueryResult {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
filters.forEach(filter => {
|
filters.forEach((filter) => {
|
||||||
filter.values = uniqBy(filter.values, v => {
|
filter.values = uniqBy(filter.values, (v) => {
|
||||||
if (moment.isMoment(v)) {
|
if (moment.isMoment(v)) {
|
||||||
return v.unix();
|
return v.unix();
|
||||||
}
|
}
|
||||||
@@ -345,12 +345,12 @@ class QueryResult {
|
|||||||
|
|
||||||
axios
|
axios
|
||||||
.get(`api/queries/${queryId}/results/${id}.json`)
|
.get(`api/queries/${queryId}/results/${id}.json`)
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
// Success handler
|
// Success handler
|
||||||
queryResult.isLoadingResult = false;
|
queryResult.isLoadingResult = false;
|
||||||
queryResult.update(response);
|
queryResult.update(response);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
// Error handler
|
// Error handler
|
||||||
queryResult.isLoadingResult = false;
|
queryResult.isLoadingResult = false;
|
||||||
handleErrorResponse(queryResult, error);
|
handleErrorResponse(queryResult, error);
|
||||||
@@ -362,10 +362,10 @@ class QueryResult {
|
|||||||
loadLatestCachedResult(queryId, parameters) {
|
loadLatestCachedResult(queryId, parameters) {
|
||||||
axios
|
axios
|
||||||
.post(`api/queries/${queryId}/results`, { queryId, parameters })
|
.post(`api/queries/${queryId}/results`, { queryId, parameters })
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
this.update(response);
|
this.update(response);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
handleErrorResponse(this, error);
|
handleErrorResponse(this, error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -375,11 +375,11 @@ class QueryResult {
|
|||||||
this.deferred.onStatusChange(ExecutionStatus.LOADING_RESULT);
|
this.deferred.onStatusChange(ExecutionStatus.LOADING_RESULT);
|
||||||
|
|
||||||
QueryResultResource.get({ id: this.job.query_result_id })
|
QueryResultResource.get({ id: this.job.query_result_id })
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
this.update(response);
|
this.update(response);
|
||||||
this.isLoadingResult = false;
|
this.isLoadingResult = false;
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
if (tryCount === undefined) {
|
if (tryCount === undefined) {
|
||||||
tryCount = 0;
|
tryCount = 0;
|
||||||
}
|
}
|
||||||
@@ -394,9 +394,12 @@ class QueryResult {
|
|||||||
});
|
});
|
||||||
this.isLoadingResult = false;
|
this.isLoadingResult = false;
|
||||||
} else {
|
} else {
|
||||||
setTimeout(() => {
|
setTimeout(
|
||||||
this.loadResult(tryCount + 1);
|
() => {
|
||||||
}, 1000 * Math.pow(2, tryCount));
|
this.loadResult(tryCount + 1);
|
||||||
|
},
|
||||||
|
1000 * Math.pow(2, tryCount)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -410,19 +413,26 @@ class QueryResult {
|
|||||||
: axios.get(`api/queries/${query}/jobs/${this.job.id}`);
|
: axios.get(`api/queries/${query}/jobs/${this.job.id}`);
|
||||||
|
|
||||||
request
|
request
|
||||||
.then(jobResponse => {
|
.then((jobResponse) => {
|
||||||
this.update(jobResponse);
|
this.update(jobResponse);
|
||||||
|
|
||||||
if (this.getStatus() === "processing" && this.job.query_result_id && this.job.query_result_id !== "None") {
|
if (this.getStatus() === "processing" && this.job.query_result_id && this.job.query_result_id !== "None") {
|
||||||
loadResult();
|
loadResult();
|
||||||
} else if (this.getStatus() !== "failed") {
|
} else if (this.getStatus() !== "failed") {
|
||||||
const waitTime = tryNumber > 10 ? 3000 : 500;
|
let waitTime;
|
||||||
|
if (tryNumber <= 10) {
|
||||||
|
waitTime = 500;
|
||||||
|
} else if (tryNumber <= 50) {
|
||||||
|
waitTime = 1000;
|
||||||
|
} else {
|
||||||
|
waitTime = 3000;
|
||||||
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.refreshStatus(query, parameters, tryNumber + 1);
|
this.refreshStatus(query, parameters, tryNumber + 1);
|
||||||
}, waitTime);
|
}, waitTime);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
logger("Connection error", error);
|
logger("Connection error", error);
|
||||||
// TODO: use QueryResultError, or better yet: exception/reject of promise.
|
// TODO: use QueryResultError, or better yet: exception/reject of promise.
|
||||||
this.update({
|
this.update({
|
||||||
@@ -451,14 +461,14 @@ class QueryResult {
|
|||||||
|
|
||||||
axios
|
axios
|
||||||
.post(`api/queries/${id}/results`, { id, parameters, apply_auto_limit: applyAutoLimit, max_age: maxAge })
|
.post(`api/queries/${id}/results`, { id, parameters, apply_auto_limit: applyAutoLimit, max_age: maxAge })
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
queryResult.update(response);
|
queryResult.update(response);
|
||||||
|
|
||||||
if ("job" in response) {
|
if ("job" in response) {
|
||||||
queryResult.refreshStatus(id, parameters);
|
queryResult.refreshStatus(id, parameters);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
handleErrorResponse(queryResult, error);
|
handleErrorResponse(queryResult, error);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -481,14 +491,14 @@ class QueryResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
QueryResultResource.post(params)
|
QueryResultResource.post(params)
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
queryResult.update(response);
|
queryResult.update(response);
|
||||||
|
|
||||||
if ("job" in response) {
|
if ("job" in response) {
|
||||||
queryResult.refreshStatus(query, parameters);
|
queryResult.refreshStatus(query, parameters);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
handleErrorResponse(queryResult, error);
|
handleErrorResponse(queryResult, error);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user