@@ -12,7 +12,7 @@ import { Observable } from 'rxjs';
12
12
import { getBackendSrv } from '@grafana/runtime' ;
13
13
import { queryLogsVolume } from './features/log/LogsModel' ;
14
14
15
- import { MyQuery , MyDataSourceOptions } from './types' ;
15
+ import { MyQuery , MyDataSourceOptions , CachedQuery } from './types' ;
16
16
import { logsErrorMessage , getConsumableTime } from 'utils/zincutils' ;
17
17
import { getOrganizations } from 'services/organizations' ;
18
18
import { cloneDeep } from 'lodash' ;
@@ -28,26 +28,59 @@ export class DataSource
28
28
instanceSettings ?: DataSourceInstanceSettings < MyDataSourceOptions > ;
29
29
url : string ;
30
30
streamFields : any [ ] ;
31
+ cachedQuery : CachedQuery ;
31
32
32
33
constructor ( instanceSettings : DataSourceInstanceSettings < MyDataSourceOptions > ) {
33
34
super ( instanceSettings ) ;
34
35
this . url = instanceSettings . url || '' ;
35
36
this . instanceSettings = instanceSettings ;
36
37
this . streamFields = [ ] ;
38
+ this . cachedQuery = {
39
+ requestQuery : '' ,
40
+ isFetching : false ,
41
+ data : null ,
42
+ promise : null ,
43
+ } ;
37
44
}
38
45
39
46
async query ( options : DataQueryRequest < MyQuery > ) : Promise < DataQueryResponse > {
40
47
const timestamps = getConsumableTime ( options . range ) ;
41
48
const promises = options . targets . map ( ( target ) => {
49
+ if ( ! this . cachedQuery . data ) {
50
+ this . cachedQuery . data = new Promise ( ( resolve , reject ) => {
51
+ this . cachedQuery . promise = {
52
+ resolve,
53
+ reject,
54
+ } ;
55
+ } ) ;
56
+ }
42
57
const reqData = buildQuery ( target , timestamps , this . streamFields ) ;
58
+ if ( JSON . stringify ( reqData ) === this . cachedQuery . requestQuery ) {
59
+ return this . cachedQuery . data
60
+ ?. then ( ( res ) => {
61
+ if ( target ?. refId ?. includes ( REF_ID_STARTER_LOG_VOLUME ) ) {
62
+ return res . graph ;
63
+ }
64
+ return res . logs ;
65
+ } )
66
+ . finally ( ( ) => {
67
+ this . resetQueryCache ( ) ;
68
+ } ) ;
69
+ }
70
+ this . cachedQuery . requestQuery = JSON . stringify ( reqData ) ;
71
+ this . cachedQuery . isFetching = true ;
43
72
return this . doRequest ( target , reqData )
44
73
. then ( ( response ) => {
74
+ const graphDataFrame = getGraphDataFrame ( response , target ) ;
75
+ const logsDataFrame = getLogsDataFrame ( response , target , this . streamFields ) ;
76
+ this . cachedQuery . promise ?. resolve ( { graph : graphDataFrame , logs : logsDataFrame } ) ;
45
77
if ( target ?. refId ?. includes ( REF_ID_STARTER_LOG_VOLUME ) ) {
46
- return getGraphDataFrame ( response , target ) ;
78
+ return graphDataFrame ;
47
79
}
48
- return getLogsDataFrame ( response , target , this . streamFields ) ;
80
+ return logsDataFrame ;
49
81
} )
50
82
. catch ( ( err ) => {
83
+ this . cachedQuery . promise ?. reject ( err ) ;
51
84
let error = {
52
85
message : '' ,
53
86
detail : '' ,
@@ -64,6 +97,9 @@ export class DataSource
64
97
error . message = customMessage ;
65
98
}
66
99
throw new Error ( error . message + ( error . detail ? ` ( ${ error . detail } ) ` : '' ) ) ;
100
+ } )
101
+ . finally ( ( ) => {
102
+ this . cachedQuery . isFetching = false ;
67
103
} ) ;
68
104
} ) ;
69
105
@@ -78,6 +114,15 @@ export class DataSource
78
114
} ) ;
79
115
}
80
116
117
+ resetQueryCache ( ) {
118
+ this . cachedQuery = {
119
+ requestQuery : '' ,
120
+ isFetching : false ,
121
+ data : null ,
122
+ promise : null ,
123
+ } ;
124
+ }
125
+
81
126
async testDatasource ( ) {
82
127
return getOrganizations ( { url : this . url } )
83
128
. then ( ( res ) => {
0 commit comments