Skip to content
This repository has been archived by the owner on Apr 2, 2024. It is now read-only.

Propagate context from query requests #1610

Merged
merged 1 commit into from
Sep 8, 2022

Conversation

alejandrodnm
Copy link
Contributor

@alejandrodnm alejandrodnm commented Sep 1, 2022

Description

Propagate context from query requests

Each http.Request comes with its own context, in the case the client
connection closes this context is cancelled.

Propagating the request context prevents the request handler from doing
extra work in situations when the client is not going to be able to
receive the response.

For supporting context propagation, the same approach from the
Prometheus codebase was followed. Every Queryable method that returns
a Querier accepts a context, it's the Querier responsibility to
propagate it downstream.

Even though endpoints like /api/v1/query and /api/v1/query_range
already propagated the context to downstream functions to the
SamplesQuerier to handle the timeout parameter of the request, the
Querier was not using the given context in the calls to the PgxConn
methods, it was using context.Background() instead.

An important consideration to keep in mind: cancelling the
context on a request for a running query will abort the connection to the
database but not the query. To cancel the query we might have to use
something like statement_timeout as proposed by
#1232 .

closes #1205

Merge requirements

Please take into account the following non-code changes that you may need to make with your PR:

  • CHANGELOG entry for user-facing changes
  • Updated the relevant documentation

@alejandrodnm alejandrodnm force-pushed the adn/query-ctx-propagation branch 2 times, most recently from e9ee3dd to dcb9ffe Compare September 2, 2022 08:28
@alejandrodnm alejandrodnm changed the title Propagate the context from the request Propagate context from query requests Sep 2, 2022
@alejandrodnm alejandrodnm marked this pull request as ready for review September 2, 2022 13:59
Copy link
Contributor

@cevian cevian left a comment

Choose a reason for hiding this comment

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

Overall, this looks good. I'd like to see some tests about what happens if the context expires but am not 100% positive it's practical to do without creating flaky tests. It's worth thinking about and considering whether such tests are possible though,

Each http.Request comes with its own context, in the case the client
connection closes this context is cancelled.

Propagating the request context prevents the request handler from doing
extra work in situations when the client is not going to be able to
receive the response.

For supporting context propagation, the same approach from the
Prometheus codebase was followed. Every `Queryable` method that returns
a `Querier` accepts a context, it's the `Querier` responsibility to
propagate it downstream.

- Prometheus `Queryable` interface definition:
https://github.com/prometheus/prometheus/blob/15fa34936b6f1febe896ecee0f49889a56347762/storage/interface.go#L79-L84

- Prometheus `Querier` propagating the ctx in the `Select` method:
https://github.com/prometheus/prometheus/blob/15fa34936b6f1febe896ecee0f49889a56347762/storage/remote/read.go#L170

Even though endpoints like `/api/v1/query` and `/api/v1/query_range` were
already propagating the context to downstream functions up to the
`SamplesQuerier` to handle the `timeout` parameter of the request, the
`Querier` was not using the given context in the calls to the `PgxConn`
methods, it was using `context.Background()` instead.

An important consideration to keep in mind: cancelling the
context on a request for a running query will abort the connection to the
database but not the query. To cancel the query we might have to use
something like `statement_timeout` as proposed by
#1232 .
@alejandrodnm
Copy link
Contributor Author

Overall, this looks good. I'd like to see some tests about what happens if the context expires but am not 100% positive it's practical to do without creating flaky tests. It's worth thinking about and considering whether such tests are possible though,

I don't think it's practical either. A cancelled context will be returned as an error. As I see it, the error path should be handled and tested independent of what type of error is returned during the lifecycle of a request, unless there's specific code executed depending on the type of error that's returned.

With regards to these changes, the tests could be asserting that the same ctx that's given by the request is the same that's ultimately passed to the pgx methods. Given the amount of things in between, I'd say this tests won't be easy to set up and won't provide much value. I think we are ok relying on the contract that we are propagating the context and that pgx and the http library honor that contract.

In the case of end 2 end the problem would be that depending on when the context is cancelled we would be testing different parts of the code. If the context is cancelled immediately we would only test the first check for the cancelled context, if the context is cancelled randomly then we won't be really sure what to assert.

Of course, I'm open to ideas, because I don't have any good one for this.

Copy link
Member

@arajkumar arajkumar left a comment

Choose a reason for hiding this comment

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

lgtm

@alejandrodnm alejandrodnm merged commit 1151221 into master Sep 8, 2022
@alejandrodnm alejandrodnm deleted the adn/query-ctx-propagation branch September 8, 2022 08:05
@alejandrodnm alejandrodnm mentioned this pull request Oct 4, 2022
2 tasks
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Use incoming context from query endpoints
3 participants