mirror of
https://github.com/valitydev/redash.git
synced 2024-11-06 17:15:17 +00:00
Return cached data source schema when available (#4934)
This commit is contained in:
parent
733bc1c109
commit
100c7be5e0
@ -1,11 +1,11 @@
|
|||||||
import { reduce } from "lodash";
|
import { reduce, has } from "lodash";
|
||||||
import { useCallback, useEffect, useRef, useState, useMemo } from "react";
|
import { useCallback, useEffect, useRef, useState, useMemo } from "react";
|
||||||
import { axios } from "@/services/axios";
|
import { axios } from "@/services/axios";
|
||||||
import DataSource, { SCHEMA_NOT_SUPPORTED } from "@/services/data-source";
|
import DataSource, { SCHEMA_NOT_SUPPORTED } from "@/services/data-source";
|
||||||
import notification from "@/services/notification";
|
import notification from "@/services/notification";
|
||||||
|
|
||||||
function sleep(ms) {
|
function sleep(ms) {
|
||||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSchema(dataSource, refresh = undefined) {
|
function getSchema(dataSource, refresh = undefined) {
|
||||||
@ -13,11 +13,10 @@ function getSchema(dataSource, refresh = undefined) {
|
|||||||
return Promise.resolve([]);
|
return Promise.resolve([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchSchemaFromJob = (data) => {
|
const fetchSchemaFromJob = data => {
|
||||||
return sleep(1000).then(() => {
|
return axios.get(`api/jobs/${data.job.id}`).then(data => {
|
||||||
return axios.get(`api/jobs/${data.job.id}`).then((data) => {
|
|
||||||
if (data.job.status < 3) {
|
if (data.job.status < 3) {
|
||||||
return fetchSchemaFromJob(data);
|
return sleep(1000).then(() => fetchSchemaFromJob(data));
|
||||||
} else if (data.job.status === 3) {
|
} else if (data.job.status === 3) {
|
||||||
return data.job.result;
|
return data.job.result;
|
||||||
} else if (data.job.status === 4 && data.job.error.code === SCHEMA_NOT_SUPPORTED) {
|
} else if (data.job.status === 4 && data.job.error.code === SCHEMA_NOT_SUPPORTED) {
|
||||||
@ -26,11 +25,15 @@ function getSchema(dataSource, refresh = undefined) {
|
|||||||
return Promise.reject(new Error(data.job.error));
|
return Promise.reject(new Error(data.job.error));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return DataSource.fetchSchema(dataSource, refresh)
|
return DataSource.fetchSchema(dataSource, refresh)
|
||||||
.then(fetchSchemaFromJob)
|
.then(data => {
|
||||||
|
if (has(data, "job")) {
|
||||||
|
return fetchSchemaFromJob(data);
|
||||||
|
}
|
||||||
|
return has(data, "schema") ? data.schema : Promise.reject();
|
||||||
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
notification.error("Schema refresh failed.", "Please try again later.");
|
notification.error("Schema refresh failed.", "Please try again later.");
|
||||||
return Promise.resolve([]);
|
return Promise.resolve([]);
|
||||||
@ -48,9 +51,11 @@ export default function useDataSourceSchema(dataSource) {
|
|||||||
|
|
||||||
const reloadSchema = useCallback(
|
const reloadSchema = useCallback(
|
||||||
(refresh = undefined) => {
|
(refresh = undefined) => {
|
||||||
const refreshToken = Math.random().toString(36).substr(2);
|
const refreshToken = Math.random()
|
||||||
|
.toString(36)
|
||||||
|
.substr(2);
|
||||||
refreshSchemaTokenRef.current = refreshToken;
|
refreshSchemaTokenRef.current = refreshToken;
|
||||||
getSchema(dataSource, refresh).then((data) => {
|
getSchema(dataSource, refresh).then(data => {
|
||||||
if (refreshSchemaTokenRef.current === refreshToken) {
|
if (refreshSchemaTokenRef.current === refreshToken) {
|
||||||
setSchema(prepareSchema(data));
|
setSchema(prepareSchema(data));
|
||||||
}
|
}
|
||||||
|
@ -187,6 +187,12 @@ class DataSourceSchemaResource(BaseResource):
|
|||||||
require_access(data_source, self.current_user, view_only)
|
require_access(data_source, self.current_user, view_only)
|
||||||
refresh = request.args.get("refresh") is not None
|
refresh = request.args.get("refresh") is not None
|
||||||
|
|
||||||
|
if not refresh:
|
||||||
|
cached_schema = data_source.get_cached_schema()
|
||||||
|
|
||||||
|
if cached_schema is not None:
|
||||||
|
return {"schema": cached_schema}
|
||||||
|
|
||||||
job = get_schema.delay(data_source.id, refresh)
|
job = get_schema.delay(data_source.id, refresh)
|
||||||
|
|
||||||
return serialize_job(job)
|
return serialize_job(job)
|
||||||
|
@ -182,12 +182,16 @@ class DataSource(BelongsToOrgMixin, db.Model):
|
|||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def get_schema(self, refresh=False):
|
def get_cached_schema(self):
|
||||||
cache = None
|
|
||||||
if not refresh:
|
|
||||||
cache = redis_connection.get(self._schema_key)
|
cache = redis_connection.get(self._schema_key)
|
||||||
|
return json_loads(cache) if cache else None
|
||||||
|
|
||||||
if cache is None:
|
def get_schema(self, refresh=False):
|
||||||
|
out_schema = None
|
||||||
|
if not refresh:
|
||||||
|
out_schema = self.get_cached_schema()
|
||||||
|
|
||||||
|
if out_schema is None:
|
||||||
query_runner = self.query_runner
|
query_runner = self.query_runner
|
||||||
schema = query_runner.get_schema(get_stats=refresh)
|
schema = query_runner.get_schema(get_stats=refresh)
|
||||||
|
|
||||||
@ -200,8 +204,6 @@ class DataSource(BelongsToOrgMixin, db.Model):
|
|||||||
out_schema = schema
|
out_schema = schema
|
||||||
finally:
|
finally:
|
||||||
redis_connection.set(self._schema_key, json_dumps(out_schema))
|
redis_connection.set(self._schema_key, json_dumps(out_schema))
|
||||||
else:
|
|
||||||
out_schema = json_loads(cache)
|
|
||||||
|
|
||||||
return out_schema
|
return out_schema
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user