SharedQueryRunner.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import { DataSourceApi, DataQuery, PanelData } from '@grafana/ui';
  2. import { PanelQueryRunner, QueryRunnerOptions } from 'app/features/dashboard/state/PanelQueryRunner';
  3. import { toDataQueryError } from 'app/features/dashboard/state/PanelQueryState';
  4. import { DashboardQuery } from './types';
  5. import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
  6. import { Unsubscribable } from 'rxjs';
  7. import { PanelModel } from 'app/features/dashboard/state';
  8. import { LoadingState } from '@grafana/data';
  9. export const SHARED_DASHBODARD_QUERY = '-- Dashboard --';
  10. export function isSharedDashboardQuery(datasource: string | DataSourceApi) {
  11. if (!datasource) {
  12. // default datasource
  13. return false;
  14. }
  15. if (datasource === SHARED_DASHBODARD_QUERY) {
  16. return true;
  17. }
  18. const ds = datasource as DataSourceApi;
  19. return ds.meta && ds.meta.name === SHARED_DASHBODARD_QUERY;
  20. }
  21. export class SharedQueryRunner {
  22. private containerPanel: PanelModel;
  23. private listenToPanelId: number;
  24. private listenToPanel: PanelModel;
  25. private listenToRunner: PanelQueryRunner;
  26. private subscription: Unsubscribable;
  27. constructor(private runner: PanelQueryRunner) {
  28. this.containerPanel = getDashboardSrv()
  29. .getCurrent()
  30. .getPanelById(runner.getPanelId());
  31. }
  32. process(options: QueryRunnerOptions): Promise<PanelData> {
  33. const panelId = getPanelIdFromQuery(options.queries);
  34. if (!panelId) {
  35. this.disconnect();
  36. return getQueryError('Missing panel reference ID');
  37. }
  38. // The requested panel changed
  39. if (this.listenToPanelId !== panelId) {
  40. this.disconnect();
  41. this.listenToPanel = getDashboardSrv()
  42. .getCurrent()
  43. .getPanelById(panelId);
  44. if (!this.listenToPanel) {
  45. return getQueryError('Unknown Panel: ' + panelId);
  46. }
  47. this.listenToPanelId = panelId;
  48. this.listenToRunner = this.listenToPanel.getQueryRunner();
  49. this.subscription = this.listenToRunner.chain(this.runner);
  50. this.runner.setState(this.listenToRunner.getState());
  51. console.log('Connecting panel: ', this.containerPanel.id, 'to:', this.listenToPanelId);
  52. }
  53. // If the target has refreshed recently, use the exising data
  54. const data = this.listenToRunner.getCurrentData();
  55. if (data.request && data.request.startTime) {
  56. const elapsed = Date.now() - data.request.startTime;
  57. if (elapsed < 150) {
  58. return Promise.resolve(data);
  59. }
  60. }
  61. // When fullscreen run with the current panel settings
  62. if (this.containerPanel.fullscreen) {
  63. const { datasource, targets } = this.listenToPanel;
  64. const modified = {
  65. ...options,
  66. panelId,
  67. datasource,
  68. queries: targets,
  69. };
  70. return this.listenToRunner.run(modified);
  71. } else {
  72. this.listenToPanel.refresh();
  73. }
  74. return Promise.resolve(data);
  75. }
  76. disconnect() {
  77. if (this.subscription) {
  78. this.subscription.unsubscribe();
  79. this.subscription = null;
  80. }
  81. if (this.listenToPanel) {
  82. this.listenToPanel = null;
  83. }
  84. this.listenToPanelId = undefined;
  85. }
  86. }
  87. function getPanelIdFromQuery(queries: DataQuery[]): number | undefined {
  88. if (!queries || !queries.length) {
  89. return undefined;
  90. }
  91. return (queries[0] as DashboardQuery).panelId;
  92. }
  93. function getQueryError(msg: string): Promise<PanelData> {
  94. return Promise.resolve({
  95. state: LoadingState.Error,
  96. series: [],
  97. legacy: [],
  98. error: toDataQueryError(msg),
  99. });
  100. }