SharedQueryRunner.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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. console.log('Connecting panel: ', this.containerPanel.id, 'to:', this.listenToPanelId);
  51. }
  52. // If the target has refreshed recently, use the exising data
  53. const data = this.listenToRunner.getCurrentData();
  54. if (data.request && data.request.startTime) {
  55. const elapsed = Date.now() - data.request.startTime;
  56. if (elapsed < 150) {
  57. return Promise.resolve(data);
  58. }
  59. }
  60. // When fullscreen run with the current panel settings
  61. if (this.containerPanel.fullscreen) {
  62. const { datasource, targets } = this.listenToPanel;
  63. const modified = {
  64. ...options,
  65. panelId,
  66. datasource,
  67. queries: targets,
  68. };
  69. return this.listenToRunner.run(modified);
  70. } else {
  71. this.listenToPanel.refresh();
  72. }
  73. return Promise.resolve(data);
  74. }
  75. disconnect() {
  76. if (this.subscription) {
  77. this.subscription.unsubscribe();
  78. this.subscription = null;
  79. }
  80. if (this.listenToPanel) {
  81. this.listenToPanel = null;
  82. }
  83. this.listenToPanelId = undefined;
  84. }
  85. }
  86. function getPanelIdFromQuery(queries: DataQuery[]): number | undefined {
  87. if (!queries || !queries.length) {
  88. return undefined;
  89. }
  90. return (queries[0] as DashboardQuery).panelId;
  91. }
  92. function getQueryError(msg: string): Promise<PanelData> {
  93. return Promise.resolve({
  94. state: LoadingState.Error,
  95. series: [],
  96. legacy: [],
  97. error: toDataQueryError(msg),
  98. });
  99. }