Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explore: Use PanelQueryState to handle querying #18694

Merged
merged 12 commits into from Aug 28, 2019

Conversation

hugohaggmark
Copy link
Contributor

@hugohaggmark hugohaggmark commented Aug 23, 2019

What this PR does / why we need it:
Completely replaces existing epics with PanelQueryState in Explore. Reasoning behind this is that we're no longer using the RxJs part of epics because they have been replaced by PanelQueryState. So to minimize complexity I transformed existing epics to Thunks.

Which issue(s) this PR fixes:

Special notes for your reviewer:
Tested with both Loki and Prometheus and it seems to work. Had to remove the feature where Prom instant is returned first and then the TimeSeries. Reverted back to returning all.

unsubscribe: () => undefined,
};

return state;
if (query.instant) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hack until we implement can use sub requests.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does not need sub requests -- just a different key

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note the changes in #16676 are not required for sub requests, that really just uses them for the mixed query datasource and also adds work to better report it in the editor UI. Multi-request streaming is already supported, but no built-in datasources use it (yet)... partly because keeping in sync with explore

let newRange = request.range;
let absoluteRange: AbsoluteTimeRange = {
from: newRange.from.valueOf(),
to: newRange.to.valueOf(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to do any of this part... it already happened in validateStreamsAndGetPanelData()

you can just use the request.range

Copy link
Member

@ryantxu ryantxu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have enough knowledge about redux or epics to say anything helpful in that domain.

calling queryState seems good though :)

@ryantxu
Copy link
Member

ryantxu commented Aug 26, 2019

@hugohaggmark -- Check if the changes in #18674 are useful for you... if yes, you can merge them into this, otherwise I will just remove that PR. And obviously if any other change to panelQueryState would make your interaction smoother we should do that.

@hugohaggmark hugohaggmark changed the title WIP: inital POC Explore: Use PanelQueryState to handle querying Aug 27, 2019
@hugohaggmark hugohaggmark added the pr/needs-manual-testing Before merge some help with manual testing & verification is requested label Aug 27, 2019
@hugohaggmark hugohaggmark added this to the 6.4 milestone Aug 27, 2019
}

if (state === LoadingState.Streaming) {
dispatch(limitMessageRate(exploreId, isLokiDataSource ? series : legacy, datasourceId));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to replace the call to limitMessageRate with processQueryResults and implement throttling in datasources instead because Prometheus datasource uses this as a way to run Instant and TimeSeries queries in parallel.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

throttling is interesting -- there are two ways we may want to throttle:

  • listener reading messages from the server (dropped values are ok)
  • notification updates in the panel/explore (the refresh rate)

In #18728, I looked at how we could maybe make these part of the standard request object. Maybe something like:

interface ObserverConfig {
  pause?: boolean;
  throttle?: number;
}

export interface StreamingQueryOptions {
  ...
  listener?: ObserverConfig;
  notification?: ObserverConfig;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hugohaggmark limitMessageRate does not actually limit anything right now does it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope because of the reason in my comment, it would break Prometheus queries.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More details: to make Prometheus parallel querying work with PanelQueryState I use the streaming callback. But after posting each query's result I immediately send a "stop this stream" kind of result as well. If we then throttle/debounce that it will miss the first result with the data. So I'm just passing data along, I'm currently simplifying this even further in next PR so limitMessageRate will go away and also @ryantxu is adding buffering directly to the Loki datasource.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So is there anything to do on my side? I mean seems like my work with the buffering was kinda hijacked :D. Should I just wait for @ryantxu and reuse that work afterwards?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry didn't mean to hijack your work but I think you'll have to move your part to the loki datasource for now. Let me know if you need help with that. And yes it's hard to sync 3 ongoing efforts

// but we're using the datasource interval limit for now
const interval = datasourceInstance.interval;

if (!queryState.isStarted()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there should not be the negation, should it? Also seems like this could use the stopQueryState utility function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Will fix

@@ -114,6 +116,7 @@ export const makeExploreItemState = (): ExploreItemState => ({
mode: null,
isLive: false,
urlReplaced: false,
queryState: new PanelQueryState(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this. I feel like this should not be accessible by the react and also does not drive rendering in any. We do not change it and it is also mutable. So I wonder if we shouldn't just move it outside of the redux store and handle it as external dependency kind of thing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think this is fine for now, it is mutable so not ideal to have in redux but not forbidden either. Think before we do more complex work figure out the proper redux solution around this we can move ahead with this. I think the coming rewrite to how queries are executed to use observable patterns, that will fundamentally change things so good to wait to do more work around the current API & responsibility of PanelQueryState as I think that will change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good points! But I'll let it be for now.

}

if (state === LoadingState.Streaming) {
dispatch(limitMessageRate(exploreId, isLokiDataSource ? series : legacy, datasourceId));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hugohaggmark limitMessageRate does not actually limit anything right now does it?

@@ -401,11 +431,304 @@ export function modifyQueries(
*/
export function runQueries(exploreId: ExploreId): ThunkResult<void> {
return (dispatch, getState) => {
dispatch(updateTimeRangeAction({ exploreId }));
dispatch(runQueriesAction({ exploreId }));
dispatch(updateTime({ exploreId }));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a note, not sure if this is because I already know what this should be doing, but I find this a bit more readable than before.

Copy link
Member

@torkelo torkelo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have tested this quite a bit, with Prometheus, Loki, InfluxDB, Elasticsearch, Postgres, Graphite.

Looks to work really well. Seems to even fix some current issues I have seen with being stuck in a loading state when switching data sources or logs mode.

I have found some issues with Elasticsearch that I am yet not sure is related to this PR or existing issues in master. Will investigate more. But mergeable soon!

@torkelo
Copy link
Member

torkelo commented Aug 28, 2019

Merging this now to aid further development in other PRs. But need to investigate more the issue with Elasticsearch (query editor shows error box but otherwise works great), Elasticsearch Logs is also not working (think due to time field losing its time type somewhere).

But can be fixed in a PR tomorrow

@torkelo torkelo merged commit 5ca643f into master Aug 28, 2019
Observability (deprecated, use Observability Squad) automation moved this from Under review to Done Aug 28, 2019
@torkelo torkelo deleted the hugoh/use-panelQueryDataInExplore branch August 28, 2019 16:24
ryantxu added a commit to ryantxu/grafana that referenced this pull request Aug 28, 2019
* grafana/master:
  Explore: Use PanelQueryState to handle querying (grafana#18694)
  Chore: Improve err message for notifications (grafana#18757)
  @grafana/toolkit: add package versions to the ci report (grafana#18751)
  @grafana/data: Matchers and Transforms (grafana#16756)
  Docs: Document LDAP config reload in admin http api (grafana#18739)
  center NoDataSourceCallToActionCard in Explore (grafana#18752)
  DataLinks: enable data links in Gauge, BarGauge and SingleStat2 panel (grafana#18605)
  DashboardDatasource: reuse query results within a dashboard (grafana#16660)
  Plugins: show a clear error on the plugin page when it failed to load (grafana#18733)
  Chore: Use ruleId instead of alertId as log keyword (grafana#18738)
  @grafana/data: improve the CircularVector api (grafana#18716)
  QueryEditor: check if optional func toggleEditorMode is provided (grafana#18705)
  Emails: remove the yarn.lock (grafana#18724)
  OAuth: Support JMES path lookup when retrieving user email (grafana#14683)
  Emails: resurrect template notification (grafana#18686)
  Email: add reply-to and direct attachment (grafana#18715)
  Dashboard: Adds Logs Panel (alpha) as visualization option for Dashboards (grafana#18641)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/explore area/streaming pr/needs-manual-testing Before merge some help with manual testing & verification is requested type/refactor
Development

Successfully merging this pull request may close these issues.

None yet

4 participants